• Python网络爬虫(一)


    Urllib发送请求

    基本用法

    基本的用法就是调用request库,
    class urllib.request.Request(url, data=None, headers={}, origin_req_host=None, unverifiable=False, method=None)在编写代码之前把这些属性值填写成自己想要的参数就行了,

    高级用法

    将介绍“处理器“---Handler。利用它就可以处理Cookies、设置代理等任何HTTP请求中所有的事情。
    首先介绍下 urllib.request 模块里的 BaseHandler类,它是所有其他 Handler 的父类,它提供了最基本的 Handler 的方法,例如 default_open()、protocol_request() 方法等。接下来就有各种 Handler 子类继承这个 BaseHandler 类,举例几个如下:

    • HTTPDefaultErrorHandler 用于处理 HTTP 响应错误,错误都会抛出 HTTPError 类型的异常。
    • HTTPRedirectHandler 用于处理重定向。
    • HTTPCookieProcessor 用于处理 Cookies。
    • ProxyHandler 用于设置代理,默认代理为空。
    • HTTPPasswordMgr 用于管理密码,它维护了用户名密码的表。
    • HTTPBasicAuthHandler 用于管理认证,如果一个链接打开时需要认证,那么可以用它来解决认证问题。
      更多的Handler可以参考https://docs.python.org/3/library/urllib.request.html#basehandler-objects
      在正常的request中需要使用urlopen,而handler则是需要使用Opener,urlopen()这个方法就是Urllib为我们提供的一个Opener。

    认证

    有些网站必须要输入用户名和密码,认证成功后才能继续显示。类似的网站比如路由器的管理员登录界面(在浏览器中输入192.168.1.1跳转的界面)。在这里并不是绕过登录界面,而是在模拟请求的时候不会报错。

    from urllib.request import HTTPPasswordMgrWithDefaultRealm, HTTPBasicAuthHandler, build_opener
    from urllib.error import URLError
    
    username = 'username'
    password = 'password'
    url = 'http://localhost:5000/'
    
    p = HTTPPasswordMgrWithDefaultRealm()
    p.add_password(None, url, username, password)
    auth_handler = HTTPBasicAuthHandler(p)
    opener = build_opener(auth_handler)
    
    try:
        result = opener.open(url)
        html = result.read().decode('utf-8')
        print(html)
    except URLError as e:
        print(e.reason)
    

    代理

    设置代理

    from urllib.error import URLError
    from urllib.request import ProxyHandler, build_opener
    
    proxy_handler = ProxyHandler({
        'http': 'http://127.0.0.1:9743',
        'https': 'https://127.0.0.1:9743'
    })
    opener = build_opener(proxy_handler)
    try:
        response = opener.open('https://www.baidu.com')
        print(response.read().decode('utf-8'))
    except URLError as e:
        print(e.reason)
    

    首先花点时间介绍一下Cookies,登录网站的时候我们常常会发现有些网站自动登录了,而且很长时间都不会失效、有些则是需要我们重新登录(输入用户模型和密码的),这其实涉及到了Session和Cookies的相关知识。HTTP协议是一种无状态的协议,意思是客户端与服务端进行数据交互的时候并不会保存进行的操作,举个例子:当我们加载网页的一张图片,传过来只有半张时停止加载,我们如果不加处理的再去向服务器请求,服务端是不会记住之前传输的操作的,服务端所进行的操作是重新将这张图片完整的数据重新传输一次。所以,HTTP 的无状态是指 HTTP 协议对事务处理是没有记忆能力的,也就是说服务器不知道客户端是什么状态。。这点虽然避免了信息的冗余性(不会要求HTTP协议在进行数据传输时仍然要保存事务处理),但是对于需要用户登录的页面来说,为了保持前后状态,我们肯定不希望将前面的请求全部重传一次,这样过于浪费资源了,所以保持HTTP连接状态的技术就出现了。Session在服务端(网站的服务器),用于保存用户的会话信息,Cookies在客户端。服务器通过识别 Cookies 并鉴定出是哪个用户,然后再判断用户是否是登录状态,然后返回对应的 Response。所以,我们可以这样理解:如果我们将一次登陆成功后的Cookies放在Request Headers里面直接请求服务端,就不必重新模拟登陆了。
    当浏览器下一次再请求该网站时,浏览器会把此Cookies 放到 Request Headers 一起提交给服务器,Cookies 携带了 Session ID 信息,服务器检查该 Cookies 即可找到对应的 Session 是什么,然后再判断 Session 来以此来辨认用户状态。所以我们在登录某个网站的时候,登录成功后服务器会告诉客户端设置哪些 Cookies 信息,在后续访问页面时客户端会把 Cookies 发送给服务器,服务器再找到对应的 Session 加以判断,如果 Session 中的某些设置登录状态的变量是有效的,那就证明用户是处于登录状态的,即可返回登录之后才可以查看的网页内容,浏览器进行解析便可以看到了。
    好了,下面我们介绍python中与Cookies相关的Handler,首先将网站的Cookies获取下来:

    import http.cookiejar, urllib.request
    
    cookie = http.cookiejar.CookieJar()    #申明一个CookieJar对象
    handler = urllib.request.HTTPCookieProcessor(cookie) #创建Handler
    opener = urllib.request.build_opener(handler)   #构建出Opener
    response = opener.open('http://www.baidu.com')  #执行open()函数
    for item in cookie:
        print(item.name+"="+item.value)
    

    执行的结果如下:

    BAIDUID=2E65A683F8A8BA3DF521469DF8EFF1E1:FG=1
    BIDUPSID=2E65A683F8A8BA3DF521469DF8EFF1E1
    H_PS_PSSID=20987_1421_18282_17949_21122_17001_21227_21189_21161_20927
    PSTM=1474900615
    BDSVRTM=0
    BD_HOME=0
    

    以上就是Cookies的完整样貌,我们可以将这个Cookie保存下来方便我们后面调用:

    filename = 'cookies.txt'
    #cookie = http.cookiejar.MozillaCookieJar(filename)
    cookie = http.cookiejar.LWPCookieJar(filename)
    handler = urllib.request.HTTPCookieProcessor(cookie)
    opener = urllib.request.build_opener(handler)
    response = opener.open('http://www.baidu.com')
    cookie.save(ignore_discard=True, ignore_expires=True)
    

    这时的 CookieJar就需要换成 MozillaCookieJar,生成文件时需要用到它,它是 CookieJar 的子类,可以用来处理 Cookies 和文件相关的事件,读取和保存 Cookies,它可以将 Cookies 保存成 Mozilla 型浏览器的 Cookies 的格式。
    生成的cookies.txt文件如下:

    #LWP-Cookies-2.0
    Set-Cookie3: BAIDUID="0CE9C56F598E69DB375B7C294AE5C591:FG=1"; path="/"; domain=".baidu.com"; path_spec; domain_dot; expires="2084-10-14 18:25:19Z"; version=0
    Set-Cookie3: BIDUPSID=0CE9C56F598E69DB375B7C294AE5C591; path="/"; domain=".baidu.com"; path_spec; domain_dot; expires="2084-10-14 18:25:19Z"; version=0
    Set-Cookie3: H_PS_PSSID=20048_1448_18240_17944_21089_21192_21161_20929; path="/"; domain=".baidu.com"; path_spec; domain_dot; discard; version=0
    Set-Cookie3: PSTM=1474902671; path="/"; domain=".baidu.com"; path_spec; domain_dot; expires="2084-10-14 18:25:19Z"; version=0
    Set-Cookie3: BDSVRTM=0; path="/"; domain="www.baidu.com"; path_spec; discard; version=0
    Set-Cookie3: BD_HOME=0; path="/"; domain="www.baidu.com"; path_spec; discard; version=0
    

    接下来利用Cookies的LWPCookieJar格式来读取文件:

    cookie = http.cookiejar.LWPCookieJar()
    cookie.load('cookies.txt', ignore_discard=True, ignore_expires=True)
    handler = urllib.request.HTTPCookieProcessor(cookie)
    opener = urllib.request.build_opener(handler)
    response = opener.open('http://www.baidu.com')
    print(response.read().decode('utf-8')
    

    Urllib处理异常

    在跑程序获取数据中,如果程序中途遇到错误而我们没有写异常处理的时候,尽可能辛辛苦苦跑的数据就损失了;在获取豆瓣电影top250的时候,部分电影的参数不完整,导致爬虫总是会在这中途出现错误。。。更有可能的是,如果网络情况突然变更,要做异常处理,是的网络恢复的时候能继续运行程序。综上,写异常处理真的非常重要!!

    HTTPError

    • code,返回 HTTP Status Code,即状态码,比如 404 网页不存在,500 服务器内部错误等等。
    • reason,同父类一样,返回错误的原因。
    • headers,返回 Request Headers。
    from urllib import request,error
    try:
        response = request.urlopen('http://没有这个页面.com/index.htm')
    except error.HTTPError as e:
        print(e.reason, e.code, e.headers, seq='
    ')
    
    作者:YunLambert

    -------------------------------------------

    个性签名:一名会音乐、爱健身的不合格程序员

    可以Follow博主的Github哦(っ•̀ω•́)っ✎⁾⁾

  • 相关阅读:
    空值判断(is not null)
    http协议相关面试题
    Linux基本面试题。(感觉也就这几个了)
    1、了解django运行流程
    python笔试常见题
    selenium中一些可能用到的js操作
    元素判断
    二次封装
    关于在阿里云上面安装mysql遇到的一些问题。
    linux常用的一些基本命令
  • 原文地址:https://www.cnblogs.com/yunlambert/p/8511611.html
Copyright © 2020-2023  润新知