Python爬虫之 urllib、UA、代理、Cookie、Session详解丨【生长吧!Python】

  • urllib.error

    • URLError产生的原因
      • 没网
      • 服务器连接失败
      • 找不到指定服务器
      • 是OSError的子类
      • 案例v07
      '''
      案例v07
      URLError的使用
      '''
      
      from urllib import request, error
      
      if __name__ == '__main__':
      
          url = "http://www.baiiiiiiiidu.com"
      
          try:
      
              req = request.Request(url)
              rsp = request.urlopen(req)
              html = rsp.read().decode()
              print(html)
      
          except error.URLError as e:
              print("URLError: {0}".format(e.reason))
              print("URLError: {0}".format(e))
      
          except Exception as e:
              print(e)
      
        URLError: [Errno 11001] getaddrinfo failed
        URLError: <urlopen error [Errno 11001] getaddrinfo failed>
      
    • HTTPError, 是URLError的一个子类
      • 案例v08
      '''
      案例v08
      URLError的使用
      '''
      
      from urllib import request, error
      
      if __name__ == '__main__':
      
          url = "http://www.baidu.com/welcome.html"
      
          url = "http://www.sipo.gov.cn/www"
      
          try:
      
              req = request.Request(url)
              rsp = request.urlopen(req)
              html = rsp.read().decode()
              print(html)
      
          except error.HTTPError as e:
              print("HTTPError: {0}".format(e.reason))
              print("HTTPError: {0}".format(e))
      
          except error.URLError as e:
              print("URLError: {0}".format(e.reason))
              print("URLError: {0}".format(e))
      
          except Exception as e:
              print(e)
      
        HTTPError: Not Found
        HTTPError: HTTP Error 404: Not Found
      
    • 两者区别:
      • HTTPError是对应的HTTP请求的返回码错误,如果返回错误码是400以上的,则引发HTTPError
      • URLError对应的一般是网络出现问题,包括url问题
      • 关系区别:OSError-URLError-HTTPError
  • UserAgent

    • UserAgent:用户代理,简称UA,属于heads的一部分,服务器通过UA来判断访问者身份

    • 常见的UA值,使用的时候可以直接复制粘贴,也可以用浏览器访问的时候抓包

        1.Android
      
        Mozilla/5.0 (Linux; Android 4.1.1; Nexus 7 Build/JRO03D) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.166 Safari/535.19
        Mozilla/5.0 (Linux; U; Android 4.0.4; en-gb; GT-I9300 Build/IMM76D) AppleWebKit/534.30 (KHTML, like Gecko) Version/4.0 Mobile Safari/534.30
        Mozilla/5.0 (Linux; U; Android 2.2; en-gb; GT-P1000 Build/FROYO) AppleWebKit/533.1 (KHTML, like Gecko) Version/4.0 Mobile Safari/533.1
      
        2.Firefox
      
        Mozilla/5.0 (Windows NT 6.2; WOW64; rv:21.0) Gecko/20100101 Firefox/21.0
        Mozilla/5.0 (Android; Mobile; rv:14.0) Gecko/14.0 Firefox/14.0
      
        3.Google Chrome
      
        Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/27.0.1453.94 Safari/537.36
        Mozilla/5.0 (Linux; Android 4.0.4; Galaxy Nexus Build/IMM76B) AppleWebKit/535.19 (KHTML, like Gecko) Chrome/18.0.1025.133 Mobile Safari/535.19
      
        4.iOS
      
        Mozilla/5.0 (iPad; CPU OS 5_0 like Mac OS X) AppleWebKit/534.46 (KHTML, like Gecko) Version/5.1 Mobile/9A334 Safari/7534.48.3
        Mozilla/5.0 (iPod; U; CPU like Mac OS X; en) AppleWebKit/420.1 (KHTML, like Gecko) Version/3.0 Mobile/3A101a Safari/419.3
      
    • 设置UA可以通过两种方式:

      • heads
      • add_header
      • 案例v09
      '''
      案例v09
      访问一个网址
      更改自己的UserAgent进行伪装
      '''
      
      from urllib import request, error
      
      if __name__ == '__main__':
      
          url = "http://www.baidu.com"
      
          try:
      
              # 使用head方法伪装UA
              # headers = {}
              # headers['User-Agent'] = 'Mozilla/5.0 (iPad; CPU OS 5_0 like Mac OS X) AppleWebKit/534.46 (KHTML, like Gecko) Version/5.1 Mobile/9A334 Safari/7534.48.3'
              # req = request.Request(url, headers=headers)
      
              # 使用add_header 方法
              req = request.Request(url)
              req.add_header("User-Agent", "Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/27.0.1453.94 Safari/537.36")
      
              # 正常访问
              rsp = request.urlopen(req)
              html = rsp.read().decode()
              print(html)
      
          except error.HTTPError as e:
              print(e)
      
          except error.URLError as e:
              print(e)
      
          print("DONE>...........")
      
  • ProxyHandler处理(代理服务器)

    • 使用代理IP,是爬虫的常用手段
    • 代理用来隐藏真实访问中,代理也不允许频繁访问一个固定网站,所以,代理一定要很多很多
    • 基本使用步骤:
      1. 设置代理地址
      2. 创建一个ProxyHandler
      3. 创建Opener
      4. 安装Opener
    • 案例v10
    '''
    案例v10
    使用代理访问百度网站
    '''
    
    from urllib import request, error
    
    if __name__ == '__main__':
    
        url = "http://www.baidu.com"
    
        # 使用代理步骤
        # 1. 设置代理地址
        proxy = {'http': '118.26.170.209:8080'}
        # 2. 创建一个ProxyHandler
        proxy_handler = request.ProxyHandler(proxy)
        # 3. 创建Opener
        opener = request.build_opener(proxy_handler)
        # 4. 安装Opener
        request.install_opener(opener)
    
        # 现在如果访问url, 则使用代理服务器
        try:
            rsp = request.urlopen(url)
            html = rsp.read().decode()
            print(html)
    
        except error.URLError as e:
            print(e)
    
        except Exception as e:
            print(e)
    
      <urlopen error [WinError 10061] 由于目标计算机积极拒绝,无法连接。>
    
  • cookie & session

    • 由于http协议的无记忆性,人们为了弥补这个缺憾,所采用的一个补充协议
    • cookie是发放给用户(即http浏览器)的一段信息,session是保存在服务器上的对应的另一半信息,用来记录用户信息
  • cookie和session的区别

    • 存放位置不同
    • cookie不安全
    • session会保存在服务器上一定时间,会过期
    • 半个cookie保存数据不超过4k,很多浏览器限制一个站点最多保存20个
  • session的存放位置

    • 存在服务器端
    • 一般情况,session是放在内存中或者数据库中
    • 模拟cookie登陆 案例v11, 可以看到,没使用cookie则反馈网页为未登录状态
    # 案例v11
    from urllib import request
    
    if __name__ == '__main__':
    
        url = "http://www.renren.com/972301090/profile"
    
        rsp = request.urlopen(url)
    
        # print(rsp.read().decode())
    
        html = rsp.read().decode()
    
        with open("rsp.html", "w", encoding='utf-8') as f:
            f.write(html)
    
  • 使用coolie登陆

    • 直接把cookie复制下来,然后手动放入请求头,案例v12
    # 案例v12
    from urllib import request
    
    if __name__ == '__main__':
    
        url = "http://www.renren.com/972301090/profile"
    
        headers = {
            "Cookie": "anonymid=k0t4cq4s5whzwg; depovince=SX; jebecookies=254aff72-33ce-4da5-840c-2a285d3e6a30|||||; _r01_=1; JSESSIONID=abcEg3t1ZLigH-9Bsus1w; ick_login=19410208-7d7a-442a-858b-c996155af213; _de=92A46B3E308785D3496B0B0F305EAFFF; p=b9a464ff4ad809f2f9e718c0bf2b316f0; first_login_flag=1; ln_uact=18203503747; ln_hurl=http://head.xiaonei.com/photos/0/0/men_main.gif; t=455fae39c10094e5cd41ef42f092b6370; societyguester=455fae39c10094e5cd41ef42f092b6370; id=972301090; xnsid=adae9600; loginfrom=syshome; jebe_key=691baa31-674d-4088-86fd-a44c6049ebb4%7Ce3fb613f795528462326e4d7ae14d876%7C1569044131586%7C1%7C1569044137500; jebe_key=691baa31-674d-4088-86fd-a44c6049ebb4%7Ce3fb613f795528462326e4d7ae14d876%7C1569044131586%7C1%7C1569044137503; wp_fold=0"
        }
    
        req = request.Request(url, headers=headers)
    
        rsp = request.urlopen(req)
    
        html = rsp.read().decode()
    
        with open("rsp.html", "w", encoding='utf-8') as f:
            f.write(html)
    
    • http模块包含一些关于collie的模块,通过他们我们可以自动使用cookie

      • CookieJar
        • 管理存储cookie,向传出的http请求添加cookie
        • cookie存储在内存中,CookieJar实例回收后cookie将消失
      • FileCookieJar(filename, delayload=None, policy=None):
        • 使用文件管理cookie
        • filename是保存cookie的文件
      • MozillaCookieJar(filename, delayload=None, policy=None):
        • 创建与mozilla浏览器cookie.txt兼容的FileCookieJar实例
      • LwpCookieJar(filename, delayload=None, policy=None):
        • 创建与libwww-perl标准兼容的Set-Cookie3格式的FileCookieJar实例
      • 他们的关系是:CookieJar–>FileCookieJar–>MozillaCookieJar & LwpCookieJar
    • 利用cookiejar访问人人

      • 自动使用cookie登陆,大致流程是
        • 打开登陆页面后自动通过用户名密码登陆
        • 自动提取反馈回来的cookie
        • 利用提取的cookie登陆隐私页面
      • 案例v13
      # 案例v13
      from urllib import request, parse
      from http import cookiejar
      
      # 创建ccookiejar的实例
      cookie = cookiejar.CookieJar()
      
      # 生成cookie的管理器
      cookie_handle = request.HTTPCookieProcessor(cookie)
      # 创建http请求管理器
      http_handle = request.HTTPHandler()
      # 生成https管理器
      https_handle = request.HTTPSHandler()
      
      # 创建请求管理器
      opener = request.build_opener(http_handle, https_handle, cookie_handle)
      
      def login():
          '''
          负责初次登陆
          需要输入用户名密码,用来获取登陆cookie凭证
          :return:
          '''
      
          # 此url需要从登录form的action属性中提取
          url = "http://www.renren.com/PLogin.do"
      
          # 此键值需要从登陆form的两个对应input中提取name属性
          data = {
              "email": "xxx - xxxx - xxxx",
              "password": "xxxxxxx"
          }
      
          # 把数据进行编码
          data = parse.urlencode(data)
      
          # 创建一个请求对象
          req = request.Request(url, data=data.encode())
      
          # 使用opener发起请求
          rsp = opener.open(req)
      
      def getHomePage():
          url = "http://www.renren.com/972301090/profile"
      
          # 如果已经执行了login函数,则opener自动已经包含相应的cookie值
          rsp = opener.open(url)
      
          html = rsp.read().decode()
      
          with open("rsp.html", "w", encoding='utf-8') as f:
              f.write(html)
      
      if __name__ == '__main__':
          login()
          getHomePage()
      
    • handler是Handler的实例,常用参看案例代码

      • 用来处理复杂请求

          # 生成cookie的管理器
          cookie_handle = request.HTTPCookieProcessor(cookie)
          # 创建http请求管理器
          http_handle = request.HTTPHandler()
          # 生成https管理器
          https_handle = request.HTTPSHandler()
        
    • 创建handle后,使用opener打开,打开后相应的业务由相应的handler处理

    • cookie作为一个变量,打印出来,案例v14

    # 案例v14
    from urllib import request, parse
    from http import cookiejar
    
    # 创建ccookiejar的实例
    cookie = cookiejar.CookieJar()
    
    # 生成cookie的管理器
    cookie_handle = request.HTTPCookieProcessor(cookie)
    # 创建http请求管理器
    http_handle = request.HTTPHandler()
    # 生成https管理器
    https_handle = request.HTTPSHandler()
    
    # 创建请求管理器
    opener = request.build_opener(http_handle, https_handle, cookie_handle)
    
    def login():
        '''
        负责初次登陆
        需要输入用户名密码,用来获取登陆cookie凭证
        :return:
        '''
    
        # 此url需要从登录form的action属性中提取
        url = "http://www.renren.com/PLogin.do"
    
        # 此键值需要从登陆form的两个对应input中提取name属性
        data = {
            "email": "xxxxxxxx",
            "password": "xxxxxx"
        }
    
        # 把数据进行编码
        data = parse.urlencode(data)
    
        # 创建一个请求对象
        req = request.Request(url, data=data.encode())
    
        # 使用opener发起请求
        rsp = opener.open(req)
    
    if __name__ == '__main__':
        '''
        执行完login之后,会得到授权之后的cookie
        我们尝试把cookie打印出来
        '''
        login()
    
        print(cookie)
        for item in cookie:
            print(type(item))
            print(item)
            for i in dir(item):
                print(i)
    
    • cookie的属性
      • name: 名称
      • value: 值
      • domain:可以访问此cookie的域名
      • path:可以访问此cookie的页面路径
      • expires:过期时间
      • size:大小
      • Http字段
    • cookie的保存-FileCookieJar,案例v15
    # 案例v15
    from urllib import request, parse
    from http import cookiejar
    
    # 创建fileccookiejar的实例
    filename = "cookie.txt"
    cookie = cookiejar.MozillaCookieJar(filename)
    
    # 生成cookie的管理器
    cookie_handle = request.HTTPCookieProcessor(cookie)
    # 创建http请求管理器
    http_handle = request.HTTPHandler()
    # 生成https管理器
    https_handle = request.HTTPSHandler()
    
    # 创建请求管理器
    opener = request.build_opener(http_handle, https_handle, cookie_handle)
    
    def login():
        '''
        负责初次登陆
        需要输入用户名密码,用来获取登陆cookie凭证
        :return:
        '''
    
        # 此url需要从登录form的action属性中提取
        url = "http://www.renren.com/PLogin.do"
    
        # 此键值需要从登陆form的两个对应input中提取name属性
        data = {
            "email": "xxxx",
            "password": "xxxx"
        }
    
        # 把数据进行编码
        data = parse.urlencode(data)
    
        # 创建一个请求对象
        req = request.Request(url, data=data.encode())
    
        # 使用opener发起请求
        rsp = opener.open(req)
    
        # 保存cookie到文件
    
        # ignor_discard表示即使cookie将要被丢弃也要保存下来
        # ignor_expires表示如果该文件中cookie即使已经过期,保存
        cookie.save(ignore_discard=True, ignore_expires=True)
    
    
    if __name__ == '__main__':
        login()
    
    • cookie的读取,案例v16
    # 案例v16
    from urllib import request, parse
    from http import cookiejar
    
    # 创建ccookiejar的实例
    cookie = cookiejar.MozillaCookieJar()
    cookie.load('cookie.txt', ignore_discard=True, ignore_expires=True)
    
    # 生成cookie的管理器
    cookie_handle = request.HTTPCookieProcessor(cookie)
    # 创建http请求管理器
    http_handle = request.HTTPHandler()
    # 生成https管理器
    https_handle = request.HTTPSHandler()
    
    # 创建请求管理器
    opener = request.build_opener(http_handle, https_handle, cookie_handle)
    
    def getHomePage():
        url = "http://www.renren.com/972301090/profile"
    
        # 如果已经执行了login函数,则opener自动已经包含相应的cookie值
        rsp = opener.open(url)
    
        html = rsp.read().decode()
    
        with open("rsp.html", "w", encoding='utf-8') as f:
            f.write(html)
    
    if __name__ == '__main__':
        getHomePage()
    

【生长吧!Python】有奖征文火热进行中:https://bbs.huaweicloud.com/blogs/278897

(完)