zoukankan      html  css  js  c++  java
  • 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的处理包括页面需要爬取的图片基本上就是这样了。

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

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

  • 相关阅读:
    python练习:http协议介绍
    python练习(-)
    字符集与字符编码的强化理解与操作实践
    jquery设置select选中的文本
    盘点互联网巨头奉献的十大开源安全工具[转]
    $.ajax()函数
    sql事务
    json操作工具-LitJson
    接收图片二进制流并保存图片
    用Linq取两个数组的差集
  • 原文地址:https://www.cnblogs.com/ll409546297/p/11158759.html
Copyright © 2011-2022 走看看