• urllib和requests库


    目录

    正文

    1. Python3 使用urllib库请求网络

    1.1 基于urllib库的GET请求

    求百度首页www.baidu.com ,不添加请求头信息:

    复制代码
     1 import urllib.requests
     2 
     3 
     4 def get_page():
     5   url = 'http://www.baidu.com/'
     6   res = urllib.request.urlopen(url=url)
     7   page_source = res.read().decode('utf-8')
     8   print(page_source)
     9 
    10 
    11 if __name__ == '__main__':
    12   get_page()
    复制代码

    出显示百度首页的源码。但是有的网站进行了反爬虫设置,上述代码可能会返回一个40X之类的响应码,因为该网站识别出了是爬虫在访问网站,这时需要伪装一下爬虫,让爬虫模拟用户行为,给爬虫设置headers(User-Agent)属性,模拟浏览器请求网站。

    1.2 使用User-Agent伪装后请求网站

    由于urllib.request.urlopen() 函数不接受headers参数,所以需要构建一个urllib.request.Request对象来实现请求头的设置:

    复制代码
     1 import urllib.request
     2 
     3 
     4 def get_page():
     5   url = 'http://www.baidu.com'
     6   headers = {
     7     'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.146 Safari/537.36'
     8   }
     9   request = urllib.request.Request(url=url, headers=headers)
    10   res = urllib.request.urlopen(request)
    11   page_source = res.read().decode('utf-8')
    12   print(page_source)
    13 
    14 
    15 if __name__ == '__main__':
    16   get_page()
    复制代码

    添加headers参数,来模拟浏览器的行为。

    1.3 基于urllib库的POST请求,并用Cookie保持会话

    登陆ChinaUnix论坛,获取首页源码,然后访问一个文章。首先不使用Cookie看一下什么效果:

    复制代码
     1 import urllib.request
     2 import urllib.parse
     3 
     4 
     5 def get_page():
     6   url = 'http://bbs.chinaunix.net/member.php?mod=logging&action=login&loginsubmit=yes&loginhash=LcN2z'
     7   headers = {
     8     'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.146 Safari/537.36'
     9   }
    10   data = {
    11     'username': 'StrivePy',
    12     'password': 'XXX'
    13   }
    14   postdata = urllib.parse.urlencode(data).encode('utf-8')
    15   req = urllib.request.Request(url=url, data=postdata, headers=headers)
    16   res = urllib.request.urlopen(req)
    17   page_source = res.read().decode('gbk')
    18   print(page_source)
    19 
    20   url1 = 'http://bbs.chinaunix.net/thread-4263876-1-1.html'
    21   res1 = urllib.request.urlopen(url=url1)
    22   page_source1 = res1.read().decode('gbk')
    23   print(page_source1)
    24 
    25 
    26 if __name__ == '__main__':
    27   get_page()
    复制代码

    搜索源码中是否能看见用户名StrivePy,发现登陆成功,但是再请求其它文章时,显示为游客状态,会话状态没有保持。现在使用Cookie看一下效果:

    复制代码
     1 import urllib.request
     2 import urllib.parse
     3 import http.cookiejar
     4 
     5 
     6 def get_page():
     7   url = 'http://bbs.chinaunix.net/member.php?mod=logging&action=login&loginsubmit=yes&loginhash=LcN2z'
     8   headers = {
     9     'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.146 Safari/537.36'
    10   }
    11   data = {
    12     'username': 'StrivePy',
    13     'password': 'XXX'
    14   }
    15   postdata = urllib.parse.urlencode(data).encode('utf-8')
    16   req = urllib.request.Request(url=url, data=postdata, headers=headers)
    17   # 创建CookieJar对象
    18   cjar = http.cookiejar.CookieJar()
    19   # 以CookieJar对象为参数创建Cookie
    20   cookie = urllib.request.HTTPCookieProcessor(cjar)
    21   # 以Cookie对象为参数创建Opener对象
    22   opener = urllib.request.build_opener(cookie)
    23   # 将Opener安装位全局,覆盖urlopen函数,也可以临时使用opener.open()函数
    24   urllib.request.install_opener(opener)
    25   res = urllib.request.urlopen(req)
    26   page_source = res.read().decode('gbk')
    27   print(page_source)
    28 
    29   url1 = 'http://bbs.chinaunix.net/thread-4263876-1-1.html'
    30   res1 = urllib.request.urlopen(url=url1)
    31   page_source1 = res1.read().decode('gbk')
    32   print(page_source1)
    33 
    34 
    35 if __name__ == '__main__':
    36   get_page()
    复制代码

    结果显示登陆成功后,再访问其它文章时,显示为登陆状态。要将Cookie保存为文件待下次使用,可以使用MozillaCookieJar对象将Cookie保存为文件。

    复制代码
     1 import urllib.request
     2 import urllib.parse
     3 import http.cookiejar
     4 
     5 
     6 def get_page():
     7     url = 'http://bbs.chinaunix.net/member.php?mod=logging&action=login&loginsubmit=yes&loginhash=LcN2z'
     8     headers = {
     9         'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.146 Safari/537.36'
    10     }
    11     data = {
    12         'username': 'StrivePy',
    13         'password': 'XXX'
    14     }
    15     postdata = urllib.parse.urlencode(data).encode('utf-8')
    16     req = urllib.request.Request(url=url, data=postdata, headers=headers)
    17     filename = 'cookies.txt'
    18     # 创建CookieJar对象
    19     cjar = http.cookiejar.MozillaCookieJar(filename)
    20     # 以CookieJar对象为参数创建Cookie
    21     cookie = urllib.request.HTTPCookieProcessor(cjar)
    22     # 以Cookie对象为参数创建Opener对象
    23     opener = urllib.request.build_opener(cookie)
    24     # 临时使用opener来请求
    25     opener.open(req)
    26     # 将cookie保存为文件
    27     cjar.save(ignore_discard=True, ignore_expires=True)
    复制代码

    会在当前工作目录生成一个名为cookies.txtcookie文件,下次就可以不用登陆(如果cookie没有失效的话)直接读取这个文件来实现免登录访问。例如不进行登陆直接访问其中一篇文章(没登陆也可以访问,主要是看抬头是不是登陆状态):

    复制代码
     1 import http.cookiejar
     2 
     3 
     4 def get_page():
     5     url1 = 'http://bbs.chinaunix.net/thread-4263876-1-1.html'
     6     filename = 'cookies.txt'
     7     cjar = http.cookiejar.MozillaCookieJar(filename)
     8     cjar.load(ignore_discard=True, ignore_expires=True)
     9     cookie = urllib.request.HTTPCookieProcessor(cjar)
    10     opener = urllib.request.build_opener(cookie)
    11     res1 = opener.open(url1)
    12     page_source1 = res1.read().decode('gbk')
    13     print(page_source1)
    14 
    15 
    16 if __name__ == '__main__':
    17     get_page()
    复制代码

    结果显示是以登陆状态在查看这篇文章。

    1.4 基于urllib库使用代理请求

    使用代理可以有效规避爬虫被封。

    复制代码
     1 import urllib.request
     2 
     3 
     4 def proxy_test():
     5     url = 'http://myip.kkcha.com/'
     6     headers = {
     7         'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.146 Safari/537.36'
     8     }
     9     request = urllib.request.Request(url=url, headers=headers)
    10     proxy = {
    11         'http': '180.137.232.101:53281'
    12     }
    13     # 创建代理Handler对象
    14     proxy_handler = urllib.request.ProxyHandler(proxy)
    15     # 以Handler对象为参数创建Opener对象
    16     opener = urllib.request.build_opener(proxy_handler)
    17     # 将Opener安装为全局
    18     urllib.request.install_opener(opener)
    19     response = urllib.request.urlopen(request)
    20     page_source = response.read().decode('utf-8')
    21     print(page_source)
    22 
    23 
    24 if __name__ == '__main__':
    25     proxy_test()
    复制代码

    抓取到的页面应该显示代理IP,不知道什么原因,有时候能正常显示,有时候跳转到有道词典广告页!!!问题有待更进一步研究。

    2. Python3 使用requsets库访问网络

    2.1 基于requests库的GET请求

    GET方式请求http://httpbin.org测试网站。

    复制代码
     1 import requests
     2 
     3 
     4 def request_test():
     5     url = 'http://httpbin.org/get'
     6     response = requests.get(url)
     7     print(type(response.text), response.text)
     8     print(type(response.content), response.content)
     9 
    10 
    11 if __name__ == '__main__':
    12     request_test()
    复制代码

    直接得到响应体。

    1 <class 'str'> {"args":{},"headers":{"Accept":"*/*","Accept-Encoding":"gzip, deflate","Connection":"close","Host":"httpbin.org","User-Agent":"python-requests/2.18.4"},"origin":"121.61.132.191","url":"http://httpbin.org/get"}
    2 
    3 <class 'bytes'> b'{"args":{},"headers":{"Accept":"*/*","Accept-Encoding":"gzip, deflate","Connection":"close","Host":"httpbin.org","User-Agent":"python-requests/2.18.4"},"origin":"121.61.132.191","url":"http://httpbin.org/get"}
    

    GET方法中传递参数的三种方式:

    • 字典形式的参数用urllib.parse.urlencode()函数编码成url参数:
      复制代码
       1 import urllib.parse
       2 
       3 if __name__ == '__main__':
       4     base_url = 'http://httpbin.org/'
       5     params = {
       6         'key1': 'value1',
       7         'key2': 'value2'
       8     }
       9     full_url = base_url + urllib.parse.urlencode(params)
      10     print(full_url)        
      复制代码
      1 http://httpbin.org/key1=value1&key2=value2
    • 接在urllib.request.get()函数中使用params参数:
      复制代码
      1 import requests
      2 
      3 if __name__ == '__main__':
      4     payload = {
      5         'key1': 'value1',
      6         'key2': 'value2'
      7     }
      8     response = requests.get('http://httpbin.org/get', params=payload)
      9     print(response.url)        
      复制代码
      1 http://httpbin.org/key1=value1&key2=value2
    • url直接包含参数:
      1 http://httpbin.org/get?key2=value2&key1=value1

    2.2 基于requests库的POST请求,并用session保持会话

    登陆ChinaUnix论坛,获取首页源码,然后访问一个文章。首先不使用Session看一下什么效果:

    复制代码
     1 import requests
     3 
     4 
     5 def get_page():
     6   url = 'http://bbs.chinaunix.net/member.php?mod=logging&action=login&loginsubmit=yes&loginhash=LcN2z'
     7   headers = {
     8     'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.146 Safari/537.36'
     9   }
    10   data = {
    11     'username': 'StrivePy',
    12     'password': 'XXX'
    13   }
    14   response = requests.post(url=url, data=data, headers=headers)
    15   page_source = response.text
    16   print(response.status_code)
    17   print(page_source)
    18 
    19   url1 = 'http://bbs.chinaunix.net/thread-4263876-1-1.html'
    20   response1 = requests.get(url=url1, headers=headers)
    21   page_source1 = response1.text
    22   print(response1.status_code)
    23   print(page_source1)
    24 
    25 
    26 if __name__ == '__main__':
    27   get_page()
    复制代码

    结果显示访问其它文章时为游客模式。下来用session来维持会话看一下效果:

    复制代码
     1 import requests
     2 
     3 
     4 def get_page():
     5   url = 'http://bbs.chinaunix.net/member.php?mod=logging&action=login&loginsubmit=yes&loginhash=LcN2z'
     6   headers = {
     7     'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.146 Safari/537.36'
     8   }
     9   data = {
    10     'username': 'StrivePy',
    11     'password': 'XXX'
    12   }
    13   session = requests.session()
    14   response = session.post(url=url, data=data, headers=headers)
    15   page_source = response.text
    16   print(response.status_code)
    17   print(page_source)
    18 
    19   url1 = 'http://bbs.chinaunix.net/thread-4263876-1-1.html'
    20   response1 = session.get(url=url1, headers=headers)
    21   page_source1 = response1.text
    22   print(response1.status_code)
    23   print(page_source1)
    24 
    25 
    26 if __name__ == '__main__':
    27   get_page()
    复制代码

    结果显示访问其它文章时,显示为登陆状态,会话保持住了。使用session的效果类似于urllib库临时使用opener或者将opener安装为全局的效果。

    2.3 基于requests库使用代理请求

    在requests库中使用代理:

    复制代码
     1 import requests
     2 
     3 
     4 def proxy_test():
     5     url = 'http://myip.kkcha.com/'
     6     headers = {
     7         'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/65.0.3325.146 Safari/537.36'
     8     }
     9     proxy = {
    10         'https': '61.135.217.7: 80'
    11     }
    12     response = requests.get(url=url, headers=headers, proxies=proxy)
    13     print(response.text)
    14 
    15 
    16 if __name__ == '__main__':
    17     proxy_test()
    复制代码

    这个请求到的代码显示IP还是本地的网络IP,代理没起作用,具体原因有待研究。

  • 相关阅读:
    Java 开发环境配置
    JDBC数据批处理
    knockout.js简单实用教程1
    angular 入门教程1
    knockout简单实用教程3
    knockout简单实用教程2
    autofac使用笔记
    MVC WEB api 自动生成文档
    Unity IOC注入详细配置(MVC,WebApi)
    为什么php往mongo里插入整型数字8,变成了numberint(8)
  • 原文地址:https://www.cnblogs.com/p0pl4r/p/10547232.html
Copyright © 2020-2023  润新知