python之(urllib、urllib2、lxml、Selenium+PhantomJS)爬虫

  一、最近在学习网络爬虫的东西,说实话,没有怎么写过爬虫,Java里面使用的爬虫也没有怎么用过。这里主要是学习Python的时候,了解到Python爬虫的强大,和代码的简介,这里会简单的从入门看是说起,主要是了解基本的开发思路,后续会讲到scrapy框架的使用,这里主要是讲Python的爬虫入门。

  二、urllib、urllib2,这两个模块都是用来处理url请求的,这里的开始就是使用urllib和urllib2的库进行相关操作,来看一个例子:

#!/usr/bin/env python
# -*- coding:utf-8 -*-

import urllib
import urllib2

# 需要爬取的连接
url = "http://www.baidu.com"
# 模拟的浏览器
headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36"}
# 表单数据
form_data = {
        "start": "0",
        "end": "20"
    }
# 编码
data = urllib.urlencode(form_data)
# 设定请求
request = urllib2.Request(url, data=data, headers=headers)
# 访问获取结果
html = urllib2.urlopen(request).read()
print html

  说明:这里获取结果的方式,是通过代码去模拟浏览器,来达到访问的目的。这里的form_data 只是一个模拟ajax的请求,没有太大的用处。

  注意:urllib2.Request中如果存在data数据则是POST请求,反之GET

  三、上面我们获取到了结果,接下来就是解析,lxml是常用的一中解析方式,当然还存在其他解析的方式比如re,这里不详细介绍:

  1)在说解析之前,讲一下urllib2的handler:

  a、handler种类:handler分很多种,比如:cookie,proxy,auth、http等。

  b、为什么使用handler:cookie处理回话的保存问题;proxy处理ip代理,访问ip被封;auth认证处理;http处理器相关方式;

  c、处理器比较常见,在会话或者代理都有很好的应用

#!/usr/bin/env python
# -*- coding:utf-8 -*-

import urllib
import urllib2
import cookielib

# 通过CookieJar()类构建一个cookieJar()对象,用来保存cookie的值
cookie = cookielib.CookieJar()
# 通过HTTPCookieProcessor()处理器类构建一个处理器对象,用来处理cookie
# 参数就是构建的CookieJar()对象
cookie_handler = urllib2.HTTPCookieProcessor(cookie)
# 代理handler
# httpproxy_handler = urllib2.ProxyHandler({"http" : "ip:port"})
# 认证代理handler
# authproxy_handler = urllib2.ProxyHandler({"http" : "username:password@ip:port"})
# auth
# passwordMgr = urllib2.HTTPPasswordMgrWithDefaultRealm()
# passwordMgr.add_password(None, ip, username, password)
# httpauth_handler = urllib2.HTTPBasicAuthHandler(passwordMgr)
# proxyauth_handler = urllib2.ProxyBasicAuthHandler(passwordMgr)
# opener = urllib2.build_opener(httpauth_handler, proxyauth_handler)
# 构建一个自定义的opener
opener = urllib2.build_opener(cookie_handler)
# 通过自定义opener的addheaders的参数,可以添加HTTP报头参数
opener.addheaders = [("User-Agent", "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36")]
# renren网的登录接口
url = "http://www.renren.com/PLogin.do"
# 需要登录的账户密码
data = {"email":"邮箱", "password":"密码"}
# 通过urlencode()编码转换
data = urllib.urlencode(data)
# 第一次是post请求,发送登录需要的参数,获取cookie
request = urllib2.Request(url, data = data)
# 发送第一次的post请求,生成登录后的cookie(如果登录成功的话)
response = opener.open(request)
#print response.read()
# 第二次可以是get请求,这个请求将保存生成cookie一并发到web服务器,服务器会验证cookie通过
response_deng = opener.open("http://www.renren.com/410043129/profile")
# 获取登录后才能访问的页面信息
html = response_deng.read()
print html

  2)解析(lxml):

# !/usr/bin/python
# -*- coding: UTF-8 -*-
import urllib2
from lxml import etree

if __name__ == '__main__':
    # url = raw_input("请输入需要爬取图片的链接地址:")
    url = "https://www.baidu.com"
    headers = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36"}
    # 读取到的页面
    html = urllib2.urlopen(url).read()
    # 使用lxml的etree
    content = etree.HTML(html)
    # XPATH的写法
    img_list = content.xpath("//img/@src")
    # 对图片连接处理
    for link in img_list:
        try:
            if link.find("https") == -1:
                link = "https:" + link
            img = urllib2.urlopen(link).read()
            str_list = link.split("/")
            file_name = str_list[len(str_list) - 1]
            with open(file_name, "wb") as f:
                f.write(img)
        except Exception as err:
            print err

  xpath的语法参考:http://www.w3school.com.cn/xpath/xpath_syntax.asp

  3)另外一种使用方式(BeautifulSoup):

# !/usr/bin/python
# -*- coding: UTF-8 -*-
import urllib2

from bs4 import BeautifulSoupif __name__ == '__main__':
    url = "https://tieba.baidu.com/index.html"
    headers = {
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36"}
    # 读取到的页面
    html = urllib2.urlopen(url).read()
    bs = BeautifulSoup(html, "lxml")
    img_list = bs.find_all("img", attrs={"class": ""})
    # 对图片连接处理
    for img in img_list:
        try:
            link = img.get("src")
            if link.find("https") == -1:
                link = "https:" + link
            img = urllib2.urlopen(link).read()
            str_list = link.split("/")
            file_name = str_list[len(str_list) - 1]
            with open(file_name, "wb") as f:
                f.write(img)
        except Exception as err:
            print err

  四、Selenium+PhantomJS,上面的都是针对于静态的html文件进行的爬虫,但是现在的网站一般都是通过ajax动态的加载数据,这里就产生了一个问题,我们必须先把js加载完成,才能进行下一步的爬虫工作。这里也就产生了对应的框架,来做这一块的爬虫工作。

from selenium import webdriver
from bs4 import BeautifulSoup

if __name__ == '__main__':
    # 使用谷歌的浏览器
    driver = webdriver.Chrome()
    # 获取页面
    driver.get("https://www.douyu.com/directory/all")
    while True:
        # 确认解析方式
        bs = BeautifulSoup(driver.page_source, "lxml")
        # 找到对应的直播间名称
        title_list = bs.find_all("h3", attrs={"class": "DyListCover-intro"})
        # 直播间热度
        hot_list = bs.find_all("span", attrs={"class": "DyListCover-hot"})
        # 压缩成一个循环
        for title, hot in zip(title_list, hot_list):
            print title.text, hot.text
        # 执行下一页
        if driver.page_source.find("dy-Pagination-next") == -1:
            break
        driver.find_element_by_class_name("dy-Pagination-next").click()
    # 退出
    driver.quit()

  备注:我这里使用的是chrome的浏览器来执行的操作,目前因为PhantomJS已经被放弃了,不建议使用

  chromedriver.exe的下载需要到谷歌网站上下载(需要翻墙),我这里提供一个75版本的下载

  淘宝镜像下载地址:https://npm.taobao.org/mirrors/chromedriver/

  下面提供一种针对于图片后加载的处理:

   

import urllib2

import time
from selenium import webdriver

if __name__ == '__main__':
    # 使用谷歌的浏览器driver,需要chromedriver.exe支持(放在文件同目录下)
    # 项目运行时记得让浏览器全屏
    driver = webdriver.Chrome()
    # 爬取网址
    driver.get("https://www.douyu.com/directory/all")
    while True:
        # 下一页后等待加载
        time.sleep(2)
        # 屏幕滚动(这里的值,更具具体页面设置)
        for i in xrange(1, 11):
            js = "document.documentElement.scrollTop=%d" % (i * 1000)
            driver.execute_script(js)
            # 等待页面加载完成
            time.sleep(1)
        # 获取页面的图片(xpath方式)
        img_list = driver.find_elements_by_xpath("//div[@class='LazyLoad is-visible DyImg DyListCover-pic']/img")
        # 对图片连接处理
        for img in img_list:
            try:
                link = img.get_attribute("src")
                str_list = link.split("/")
                file_name = str_list[len(str_list) - 2]
                print file_name
                # 读取图片,写入本地
                img_data = urllib2.urlopen(link).read()
                with open("img/" + file_name, "wb") as f:
                    f.write(img_data)
            except Exception as err:
                print err
        # 查看是否存在下一页
        if driver.page_source.find("dy-Pagination-next") == -1:
            break
        # 如果存在则跳转至下一页
        driver.find_element_by_class_name("dy-Pagination-next").click()
    # 退出
    driver.close()

  说明:这里只是针对斗鱼的图片进行的爬虫,其他页面需要进一步修改,好了js的处理包括页面需要爬取的图片基本上就是这样了。

  该代码只是用于学习和尝试,不得用于其他作用

  五、好了这基本上,算的上入门了吧,当然你要爬取一个完整的东西,还是需要很多功夫的,我这里只是介绍基本上常用的一些库,和我自己测试使用的一些代码,以及目前涉及的不懂的地方,仅供学习吧,有什么错误的地方还请指出。我好及时改正!!

原文地址:https://www.cnblogs.com/ll409546297/p/11158759.html