精华内容
下载资源
问答
  • 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/' ...

    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"}\n

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

    • 将字典形式的参数用urllib.parse.urlencode()函数编码成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()

     

    展开全文
  • requests库 环境:Anaconda3(python3.5) urllib库 使用urllib构建一个请求响应模型 import urllib strUrl=&amp;amp;amp;quot;https://www.baidu.com/&amp;amp;amp;quot; response=urllib.request...

    写在前面的话:每一个实例的代码都会附上相应的代码片或者图片,保证代码完整展示在博客中。最重要的是保证例程的完整性!!!方便自己也方便他人~欢迎大家交流讨论~

    环境:Anaconda3(python3.5)

    urllib库

    使用urllib构建一个请求和响应模型

    import urllib
    strUrl="https://www.baidu.com/"
    response=urllib.request.urlopen(strUrl)
    print (response.read())

    运行返回:

    runfile('F:/Python/SPIDER/1.py', wdir='F:/Python/SPIDER')
    b'<html>\r\n<head>\r\n\t<script>\r\n\t\tlocation.replace(location.href.replace("https://","http://"));\r\n\t</script>\r\n</head>\r\n<body>\r\n\t<noscript><meta http-equiv="refresh" content="0;url=http://www.baidu.com/"></noscript>\r\n</body>\r\n</html>'

    这里有一个python3和python2的区别——
    python2中是import urllib2,但是python3没有urllib2即使在cmd中pip3 install urllib2也无法安装 urllib2。
    原因:python 3.X版本是不需要安装urllib2包的,urllib和urllib2包集合成在一个包了
    那现在问题是:
    在python3.x版本中,如何使用:urllib2.urlopen()?
    答:
    import urllib.request
    response=urllib.request.urlopen(“http://www.baidu.com“)

    post数据传送方式

    import urllib
    import urllib.request
    import urllib.parse
    myData={}
    myData['key1']='value1'
    myData['key2']='value2'
    myNewData=urllib.parse.urlencode(myData).encode(encoding='UTF8')#转换格式
    url="https://www.baidu.com"
    req=urllib.request.Request(url,myNewData)#新建req变量表示一个请求
    respon=urllib.request.urlopen(req)#新建respon变量表示对应req请求的一个响应
    page=respon.read().decode("utf8")#让爬到的页面为Html代码
    print(req)
    print(page)

    其中没有page=respon.read().decode("utf8")时,你爬到的非常乱
    这里写图片描述
    有了上面的格式转换,就成下面的样子,和你在网页中右键——审查元素看到的是一样的格式
    这里写图片描述

    Get方式传送数据

    import urllib
    import urllib.request
    import urllib.parse
    myData={}
    myData['key1']='value1'
    myData['key2']='value2'
    myNewData=urllib.parse.urlencode(myData)#转换格式
    url="https://passport.baidu.com/v2/?login"#百度登录界面
    newUrl=url+'?'+myNewData
    req=urllib.request.Request(newUrl)#新建req变量表示一个请求
    respon=urllib.request.urlopen(req)#新建respon变量表示对应req请求的一个响应
    page=respon.read().decode("utf8")#让爬到的页面为Html代码
    print(newUrl)
    print(page)

    运行结果:
    这里写图片描述
    其中要注意:get传送数据最主要的不同是直接修改了请求的URL,使你要传送的数据在URL上体现出来,即https://passport.baidu.com/v2/?login?key2=value2&key1=value1
    而post是将数据作为的一个参数传入,即urllib.request.Request(url,myNewData)

    requests库

    关于如何使用requests模块向网站发送http请求,获取到网页的HTML数据。
    get和post传送数据

    import requests
    myData={"key1":"value1","key2":"value2"}#要传递的数据
    response1=requests.get("https://www.baidu.com/")#无参的get请求
    response2=requests.get("https://www.baidu.com/",params=myData)#有参的get请求
    response3=requests.post("https://www.baidu.com/")#无参的post请求
    response4=requests.post("https://www.baidu.com/",data=myData)#有参的post请求
    print(response1.text)
    print(response2.text)
    print(response3.text)
    print(response4.text)
    展开全文
  • 在Python3中,有urllib库来实现请求的发送(将Python2中的urllib2已经统一至urllib库中)。 对于urllib库的疑问可以参照官网说明了解:https://docs.python.org/3/library/urllib.html urllib库 urllib库是python...

    Python爬虫之基本库urllib的使用

    在Python3中,有urllib库来实现请求的发送(将Python2中的urllib2已经统一至urllib库中)。

    对于urllib库的疑问可以参照官网说明了解:https://docs.python.org/3/library/urllib.html

    urllib库

    urllib库是python内置的HTTP请求库,包含四个模块:

    • request:最基本的HTTP请求模块,可以用来模拟发送请求。
    • error:异常处理模块,如果出现请求错误,可以对这些异常进行捕获,防止程序意外终止。
    • parse:一个工具模块,提供了许多URL的处理方法,如拆分、合并等。
    • robotparser:主要用来识别网站的robot.txt文件。

    发送请求

    urlopen()

    urllib.request的模块提供了最基本的构造HTTP请求的方法,利用它可以模拟浏览器的一个请求发起过程。

    首先给出urlopen()方法的API:urllib.request.urlopen(url, data=None, [timeout, ]***, cafile=None, capath=None, cadefault=False, context=None),后面会详细介绍各项参数意义。

    下面我们简单的调用下urlopen()方法:

    import urllib.request
    
    response = urllib.request.urlopen('https://www.python.org')
    print(response.read().decode('utf-8'))
    

    可以得到如下输出:

    <!doctype html>
    <!--[if lt IE 7]>   <html class="no-js ie6 lt-ie7 lt-ie8 lt-ie9">   <![endif]-->
    <!--[if IE 7]>      <html class="no-js ie7 lt-ie8 lt-ie9">          <![endif]-->
    <!--[if IE 8]>      <html class="no-js ie8 lt-ie9">                 <![endif]-->
    <!--[if gt IE 8]><!--><html class="no-js" lang="en" dir="ltr">  <!--<![endif]-->
    
    <head>
        <meta charset="utf-8">
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
    ....#省略
    </body>
    </html>
    

    接下来,我们看看urllib.request.urlopen()方法返回的是个是什么

    import urllib.request
    
    response = urllib.request.urlopen('https://www.python.org')
    print(type(response)) #打印response的类型
    
    

    输出如下:

    <class 'http.client.HTTPResponse'>
    

    可以发现,返回的是一个HTTPResponse类型的对象。HTTPResponse类型的对象包含read()、readinto()、hetheader(name)、fileno()等方法和status等属性。如下打印了HTTPResponse类型的方法返回及其status属性。

    import urllib.request
    
    response = urllib.request.urlopen('https://www.python.org')
    print(response.status)
    print(response.getheaders())
    
    

    输出了状态码和相应的头信息,如下:

    200
    [('Connection', 'close'), ('Content-Length', '48730'), ('Server', 'nginx'), ('Content-Type', 'text/html; charset=utf-8'), ('X-Frame-Options', 'DENY'), ('Via', '1.1 vegur'), ('Via', '1.1 varnish'), ('Accept-Ranges', 'bytes'), ('Date', 'Mon, 27 Jul 2020 07:55:36 GMT'), ('Via', '1.1 varnish'), ('Age', '2423'), ('X-Served-By', 'cache-bwi5134-BWI, cache-hkg17928-HKG'), ('X-Cache', 'HIT, HIT'), ('X-Cache-Hits', '30, 2173'), ('X-Timer', 'S1595836536.216510,VS0,VE0'), ('Vary', 'Cookie'), ('Strict-Transport-Security', 'max-age=63072000; includeSubDomains')]
    

    输出状态码200代表访问成功,常见的状态码还有404(页面未找到)400(服务器无法解析请求)、**500(服务器遇到错误)**等。

    urlopen()——data参数

    data参数是可选的,若添加此参数,需要使用bytes()方法将参数转化为bytes类型。并且请求方式将变为POST。

    为将其转化为bytes类型,我们可以用bytes()方法,同时利用urllib.parse模块里的urlencode()方法将参数字典转化为字符串作为第一个参数;第二个参数是指定编码格式。

    import urllib.request
    import urllib.parse
    mydict  = {
       'name':'Small_Fish'} 
    mydata = bytes(urllib.parse.urlencode(mydict),encoding='utf8')
    response = urllib.request.urlopen('http://httpbin.org/post',data=mydata)#该链接可以用来测试POST请求
    print(response.status)
    print(response.read())
    

    输出如下:

    200
    b'{\n  "args": {}, \n  "data": "", \n  "files": {}, \n  "form": {\n    "name": "Small_Fish"\n  }, \n  "headers": {\n    "Accept-Encoding": "identity", \n    "Content-Length": "15", \n    "Content-Type": "application/x-www-form-urlencoded", \n    "Host": "httpbin.org", \n    "User-Agent": "Python-urllib/3.7", \n    "X-Amzn-Trace-Id": "Root=1-5f1e8dbc-6aa88726e6a39100e23797ed"\n  }, \n  "json": null, \n  "origin": "117.136.19.0", \n  "url": "http://httpbin.org/post"\n}\n'
    

    可见返回的内容的"form"即为我们传递的参数,表面了是模拟表单的提交方式,以POST方式传输数据。

    urlopen()——timeout参数

    timeout参数根据字面意义大家应该就能猜到其意义了,该参数用于设置超时时间(单位:s),当发出的请求超出了该时间依然没有得到相应时,就会抛出异常,我们可以用try-except来捕获异常。

    import urllib.request
    import urllib.parse
    import urllib.error
    import socket
    
    if __name__ =="__main__":
       mydata = bytes(urllib.parse.urlencode({'name':'Small_Fish'}),encoding='utf8')
       try:
          response = urllib.request.urlopen('http://httpbin.org/post',data = mydata,timeout = 0.1)#设置超时时间为0.1s,当超过改时间没有得到相应将抛出异常
       except urllib.error.URLError as e:
          if isinstance(e.reason,socket.timeout):#判断,如果异常原因是socket.timeout则打印TIME OUT
             print('TIME OUT')
    

    输出如下:

    TIME OUT
    

    Request()

    当请求中需要加入Headers等信息时,我们就需要用到更强大的Request类来构建请求。

    API:class urllib.request.Request(url, data=None, headers={}, origin_req_host=None, unverifiable=False, method=None)

    下面直接来说参数吧:

    • url:请求的URL
    • data:同urlopen中的data,为bytes类型。如果是字典需要先用urllib.parse.urlencode()进行编码
    • headers:请求头,是一个字典
    • origin_req_host:请求方的host名称或IP地址
    • unverifiable:表示请求是否是无法验证的,默认False。
    • method:请求的方法(GET、POST、PUT等)

    还是举一个实例:

    import urllib.request
    import urllib.parse
    
    if __name__ == '__main__':
       url = 'http://httpbin.org/post'  #参数URL
       headers = {
          'User-Agent': 'Mozilla/4.0(compatible; MISE 5.5;Windows NT)',
          'Host':'httpbin.org'}#参数Headers
       dict ={
          'name':'Small_Fish'} #参数data
       mydata = bytes(urllib.parse.urlencode(dict),encoding='utf-8')
       request =urllib.request.Request(url,data = mydata,headers = headers, method = 'POST')
       response = urllib.request.urlopen(request)#依然使用了urlopen()
       print(response.read().decode('utf8'))
    

    输出如下:

    {
      "args": {}, 
      "data": "", 
      "files": {}, 
      "form": {
        "name": "Small_Fish"
      }, 
      "headers": {
        "Accept-Encoding": "identity", 
        "Content-Length": "8", 
        "Content-Type": "application/x-www-form-urlencoded", 
        "Host": "httpbin.org", 
        "User-Agent": "Mozilla/4.0(compatible; MISE 5.5;Windows NT)", 
        "X-Amzn-Trace-Id": "Root=1-5f1e9458-03e22590f337243009a04b88"
      }, 
      "json": null, 
      "origin": "117.136.19.0", 
      "url": "http://httpbin.org/post"
    }
    

    观察发现我们成功设置了相应的data、headers、method,其中我们构造headers的"User-Agent"为"Mozilla/4.0(compatible; MISE 5.5;Windows NT)"是用来伪装成火狐浏览器。

    同时,我们也发现我们依然用了urlopen(),只不过这次的参数不再是url,而是一个request类型的对象。

    处理异常

    URLError

    URLError类来自urllib库的error模块,它继承自OSError类,是Error异常模块类的基类,由request模块产生的异常可以通过捕获这个类来处理。

    from urllib import request, parse, error
    import urllib
    
    mydict  = {
       'name':'Small_Fish'}
    mydata = bytes(urllib.parse.urlencode(mydict),encoding='utf8')
    try:
       response = urllib.request.urlopen('http://sbsbsbsbsb.com',data=mydata,timeout=0.1)
       print(response.status)
       print(response.read())
    except error.URLError as e:
       print(e.reason)
    

    输出:

    timed out
    

    可以看到程序没有直接报错,而是打印出了异常信息,通过这样我们可以有效避免程序异常终止。

    HTTPError

    HTTPError异常类是URLError类的子类,专门用来处理HTTP请求错误。

    HTTPError有三个属性:

    • code:返回HTTP的状态码
    • reason:返回错误的原因
    • headers:返回请求头
    from urllib import request, parse, error
    import urllib
    
    try:
       response = urllib.request.urlopen('https://a.com')
       print(response.status)
    except error.HTTPError as e:
       print(e.reason,e.code,e.Headers,sep='\n')
    

    解析链接

    urlparse()

    API:urllib.parse.urlparse(urlstring,scheme=' ',allow_fragment=True)

    该方法可以实现URL的识别和分段。

    from urllib.parse import urlparse
    
    res = urlparse('http://www.baidu.com/index/html;user?id=5#comment')
    print(type(res),res,sep='\n')
    

    输出如下:

    <class 'urllib.parse.ParseResult'>
    ParseResult(scheme='http', netloc='www.baidu.com', path='/index/html', params='user', query='id=5', fragment='comment')
    

    返回的结果为ParseResult类型的一个对象,包含了6个部分scheme, netloc, path, params, query和 fragment

    • scheme:协议(http、https)
    • netloc:域名,第一个/符合前便是netloc
    • path::访问路径
    • params:参数, ;号后面便是params
    • query:查询条件,?后是查询条件
    • fragment:锚点,用于直接定位页面内部的下拉位置

    因此我们得到了一个标准的链接格式:scheme://netloc/path;params?query#fragment

    urlunparse()

    urlunparse()构造一个URL,接受的参数是一个可迭代对象,但必须长度为6.

    from urllib.parse import urlunparse
    
    
    data = ['http','www.baidu.com','index.html','user','id=6','comment']
    res = urlunparse(data)
    print(type(res),res,sep='\n')
    
    

    输出如下:

    <class 'str'>
    http://www.baidu.com/index.html;user?id=6#comment
    

    返回的结果为str类型的一个对象,并且成功构造了相应的URL。

    urlsplit()

    urlsplit()与urlparse()非常相似,只不过不在单独解析params,只返回5个结果。

    from urllib.parse import urlsplit
    
    res = urlsplit('http://www.baidu.com/index/html;user?id=5#comment')
    print(type(res),res,sep='\n')
    

    输出如下:

    <class 'urllib.parse.SplitResult'>
    SplitResult(scheme='http', netloc='www.baidu.com', path='/index/html;user', query='id=5', fragment='comment')
    

    由结果可知uesr被加入path中了。

    urlunsplit()

    urlunsplit()构造一个URL,接受的参数是一个可迭代对象,但必须长度为,类似urlunparse()就不再放代码了。

    urljoin()

    urljoin()就是用一个链接(参数1)对另外一个新链接(参数2)缺失部分进行补充,最后返回结果。

    from urllib.parse import urljoin
    
    res = urljoin('http://www.baidu.com/index.php?id=5#comment','//www.tianmao.com')
    print(res)
    

    输出:

    http://www.tianmao.com
    

    urlencode()

    urlencode()常常用于构造GET请求参数。

    from urllib.parse import urlencode
    
    dicts = {
       'name':'Small_Fish',
       'years':21}
    base_url = 'http://www.baidu.com/'
    url = base_url + urlencode(dicts)
    
    print(url)
    
    

    输出:

    http://www.baidu.com/name=Small_Fish&years=21
    

    这个方法非常常用。有时为了更加方便地构造参数,我们会事先用字典来表示。要转化为URL参数时,只需要调用方法就行。

    quote()和unquote()

    quote()该方法可以将内容转化为URL编码的格式。因为URL中带有中文参数时,可能会导致乱码的问题,利用此方法可以将中文转化为URL编码。

    相应的unquote()可以对URL编码进行解码。

    from urllib.parse import urlencode,quote,unquote
    
    name = '帅哥'
    base_url = 'http://www.baidu.com/'
    print(base_url+name)
    url = base_url +quote(name)
    
    print(url)
    print(unquote(url))
    
    

    输出如下:

    http://www.baidu.com/帅哥
    http://www.baidu.com/%E5%B8%85%E5%93%A5
    http://www.baidu.com/帅哥
    

    如上便实现了编码和解码的过程。

    Python爬虫之requests库的使用

    requests库是在python3爬虫中相对于urllib库更强大的一个库,有了它我们可以轻松进行Cookies、登录验证、代理设置等操作。

    requests库的安装

    windows下在命令行窗口下输入pip3 install requests命令即可完成安装,非常简单。

    requests的GET请求

    HTTP中最常见的就是GET请求,下面介绍一下利用requests构建GET请求的方法。

    requests.get()

    requests中以GET方式请求网页的方法就是get,是不是非常直观呢?(相对于urllib库)

    如↓:

    import requests
    
    response = requests.get('https://www.baidu.com')
    print(type(response))
    print(response.status_code)
    print(response.text)
    

    输出如下:

    <class 'requests.models.Response'>
    200
    <!DOCTYPE html>
    
    <!--STATUS OK--><html> <head><meta http-equiv=content-type content=text/html;charset=utf-8><meta http-equiv=X-UA-Compatible content=IE=Edge><meta content=always name=referrer><link rel=stylesheet type=text/css href=https://ss1.bdstatic.com/5eN1bjq8AAUYm2zgoY3K/r/www/cache/bdorz/baidu.min.c
    ....#省略OTZ
    src=//www.baidu.com/img/gs.gif> </p> </div> </div> </div> </body> </html>
    
    

    可见requests.get()返回的是一个Response类型的对象,同时也可以调用其状态码、内容等属性了解相应结果。

    如果我们想向请求中添加参数,通过get()方法也可以很轻松实现:

    import requests
    
    param = {
       'name':'Small_Fish',
       'years':21
       }
    
    headers ={
       'User-Agent':'Mozilla/5.0',
       }
    response = requests.get('http://httpbin.org/get',params = param,headers=headers)
    print(type(response))
    print(response.status_code)
    print(response.text)
    

    输出如下:

    <class 'requests.models.Response'>
    200
    {
      "args": {
        "name": "Small_Fish", 
        "years": "21"
      }, 
      "headers": {
        "Accept": "*/*", 
        "Accept-Encoding": "gzip, deflate", 
        "Host": "httpbin.org", 
        "User-Agent": "Mozilla/5.0", 
        "X-Amzn-Trace-Id": "Root=1-5f1fcc0b-b1818391d5a51ffc4dd76471"
      }, 
      "origin": "117.136.19.0", 
      "url": "http://httpbin.org/get?name=Small_Fish&years=21"
    }
    

    requests的POST请求

    另外一种比较常见的请求方式是POST请求,使用方法也非常简单。

    import requests
    
    param = {
       'name':'Small_Fish',
       'years':'21'
       }
    response = requests.post('http://httpbin.org/post',data = param)
    print(response.text)
    
    
    

    输出如下:

    {
      "args": {}, 
      "data": "", 
      "files": {}, 
      "form": {
        "name": "Small_Fish", 
        "years": "21"
      }, 
      "headers": {
        "Accept": "*/*", 
        "Accept-Encoding": "gzip, deflate", 
        "Content-Length": "24", 
        "Content-Type": "application/x-www-form-urlencoded", 
        "Host": "httpbin.org", 
        "User-Agent": "python-requests/2.24.0", 
        "X-Amzn-Trace-Id": "Root=1-5f1fcdba-bd70c740c324e9401d5cf270"
      }, 
      "json": null, 
      "origin": "117.136.19.0", 
      "url": "http://httpbin.org/post"
    }
    
    展开全文
  • 网络数据采集之urllib库 一、urllib urllib简介 urllib是python中一个功能强大用于操作URL,并在爬虫时经常用到的一个基础库,无需额外安装,默认已经安装到python中。 官方文档地址:请点击这里 urllib的四个子模块...

    网络数据采集之urllib库

    一、urllib

    urllib简介

    urllib是python中一个功能强大用于操作URL,并在爬虫时经常用到的一个基础库,无需额外安装,默认已经安装到python中。

    官方文档地址:请点击这里

    urllib的四个子模块

    Python中urllib库包括以下四个子模块,urllib库是python的内置HTTP请求库,urllib库是一个运用于URL的包(urllib is a package that collects several modules for working with URLs)

    • urllib.request: 请求模块。用于访问和读取URLS(urllib.request for opening and reading URLs),就像在浏览器里输入网址然后回车一样,只需要给这个库方法传入URL和其他参数就可以模拟实现这个过程。
    • urllib.error :异常处理模块。包括了所有urllib.request导致的异常(urllib.error containing the exceptions raised by urllib.request),我们可以捕捉这些异常,然后进行重试或者其他操作以确保程序不会意外终止。
    • urllib.parse:解析模块。用于解析URLS(urllib.parse for parsing URLs),提供了很多URL处理方法,比如拆分、解析、合并、编码。
    • urllib.robotparser:robots.txt解析模块。用于解析robots.txt文件(urllib.robotparser for parsing robots.txt files),然后判断哪些网站可以爬,哪些网站不可以爬。

    使用urllib打开网页

    最基本的方法打开网页—urlopen
    urlopen进行简单的网站请求,不支持复杂功能如验证、cookie和其他HTTP高级功能,若要支持这些功能必须使用build_opener()函数返回的OpenerDirector对象。

    # 最基本的方法打开网页
    from urllib.request import urlopen
    
    # 通过get方法请求url
    with urlopen("http://www.baidu.com") as f:
    	# 默认返回的页面类型是bytes类型,bytes类型转换为字符串,decode方法
    	print(f.read(300).decode('utf-8')
    
    

    携带data参数打开网页

    # 携带data参数打开网页
    from urllib.parse import urlencode
    from urllib.request import urlopen
    
    data = bytes(urlencode({'word': 'hello'}), encoding='utf-8')
    response = urlopen('http://httpbin.org/post', data=data)
    print(response.read().decode('utf-8'))
    

    User-Agent伪装后请求网站

    很多网站为了防止程序爬虫爬网站照成网站瘫痪,会需要携带一些headers头部信息才能访问, 我们可以通过urllib.request.Request对象指定请求头部信息。

    User-Agent = 'Mozilla/4.0(compatibe;MSIE 5.5;Windows NT)'
    # 封装请求头部信息,模拟浏览器向服务器发起请求
    request = Request("http://httpbin.org/post", headers={'User-Agent':User-Agent})
    with urlopen(request) as f:
    	# 默认返回的页面信息是bytes类型,bytes类型转换为字符串用decode方法
    	print(f.read(300).decode('utf-8'))
    

    通过构建Request打开网页

    from urllib.request import Request
    from urllib.request import urlopen
    from urllib.parse import urlencode
    
    url = 'http://httpbin.org/post'
    headers = {
        'User-Agent': 'Mozilla/4.0(compatibe;MSIE 5.5;Windows NT)',
        'Host': 'httpbin.org'
    }
    dict = {'name': 'Germey'}
    data = bytes(urlencode(dict), encoding='utf8')
    req = Request(url=url, data=data, headers=headers, method='POST')
    response = urlopen(req)
    print(response.read().decode('utf-8'))
    

    网络数据采集之requests库

    requests官方网址:点击这里
    Requests is an elegant and simple HTTP library for Python, built for human beings.
    相比较urllib模块,requests模块要简单很多,但是需要单独安装:

    • linux系统下的安装: pip install requests

    requests库的八大主要方法:

    方法 描述
    requests.request( ) 构造一个请求,支持以下各种方法
    requests.get( ) 向html页面提交get请求的方法,对应于HTTP的GET
    requests.post( ) 向html页面提交post请求的方法,对应于HTTP的POST
    requests.head( ) 获取html头部信息的主要方法,对应于HTTP的HEAD
    requests.put( ) 向html网页提交put请求的方法,对应于HTTP的PUT
    requests.options( ) 向html页面提交options请求的方法,对应于HTTP的OPTIONS
    requests.patch( ) 向html网页提交局部修改的请求,对应于HTTP的PATCH
    requests.delete( ) 向html网页提交删除的请求,对应于HTTP的DELETE

    请求之后,服务器通过response返回数据,Response对象包含服务器返回的所有信息,也包含请求的Request信息。

    response具体参数如下图:

    属性 说明
    r.status_code HTTP请求的返回状态,200表示成功,404表示失败
    r.text HTTP响应内容的字符串形式,即url对应的页面内容
    r.content( ) HTTP响应内容的二进制形式
    r.encoding 从HTTP header中猜测响应内容的编码格式
    r.apparent_encoding 从内容中分析出响应内容的编码格式(备选编码格式)

    防止反爬1:添加headers–UserAgent

    有些网站访问时必须带有浏览器等信息,如果不传入headers就会报错。

    UserAgent是识别浏览器的一串字符串,相当于浏览器的身份证,在利用爬虫爬取网站数据时,频繁更换UserAgent可以避免触发相应的反爬机制。fake-useragent对频繁更换UserAgent提供了很好的支持,可谓防反爬利器。

    # 首先导入UserAgent:
    from fake_useragent import UserAgent
    
    def add_headers():
    	user_agent = UserAgent().random
    	# 将请求头部添加到
    	response = requests.get('http://127.0.0.1:5000', headers={'User-Agent':user_agent})
    	print(response)
    
    if __name__ == '__main__':
        add_headers()
    
    

    防止反爬2:IP代理设置–proxies

    在进行爬虫爬取时,有时候爬虫会被服务器屏蔽掉,这时候采用的方法主要有降低访问时间,通过代理IP访问。IP可以从网上抓取,或者某宝购买。

    proxies = { "http": "http://127.0.0.1:9743", "https": "https://127.0.0.1:9743",}
     response = requests.get(url, proxies=proxies)
    

    useragent和IP代理的结合使用:

    import requests
    from fake_useragent import UserAgent
    
    us = UserAgent()
    proxies = {
        'http':'http://163.125.75.233:9797',
        'https':'https://182.92.220.212:8000'
    }
    
    response = requests.get('http://47.92.255.98:8000',
                            headers={'User-Agent':us.random},
                            proxies=proxies)
    print(response)
    print(response.text)
    

    爬虫应用小案例

    京东商品信息爬取:

    from urllib.error import HTTPError
    
    import requests
    from colorama import Fore
    from fake_useragent import UserAgent
    
    def down_page(url, params=None):
        try:
            ua = UserAgent()
            headers = {'User-Agent':ua.random}
            response = requests.get(url, params, headers=headers)
        except HTTPError as e:
            print(Fore.RED + '[-] 爬取网站%s失败:%s' %(url, e.reason))
            return None
        else:
            return response.content
    
    def down_file(content=b'', filename='hello.html'):
        with open(filename, 'wb') as f:
            f.write(content)
            print(Fore.GREEN + '[+]写入文件%s成功' %(filename))
    
    if __name__ == '__main__':
        url = 'https://item.jd.com/100012015170.html'
        html = down_page(url)
        down_file(content=html)
    

    360搜索关键字提交

    from urllib.error import HTTPError
    
    import requests
    from colorama import Fore
    from fake_useragent import UserAgent
    
    def down_page(url, params):
        try:
            ua = UserAgent()
            headers = {
                'User-Agent':ua.random
            }
            response = requests.get(url, params, headers=headers)
        except HTTPError as e:
            print(Fore.RED + '[-]爬取网页%s失败:%s' %(url, e.reason))
            return None
        else:
            return response.content  # 二进制文件
    
    def down_file(content=b'',filename='python.html'):
        with open(filename, 'wb') as f:
            f.write(content)
            print(Fore.GREEN + '[+]关键字写入文件%s成功......'%(filename))
    
    if __name__ == '__main__':
        url = 'https://www.so.com/s'
        params = {
            'q' : 'python'
        }
        down_file(content = down_page(url, params))
    

    response = requests.get(url, params, headers=headers) 这里参数会自动填入访问的url网页,进行关键字查询。

    展开全文
  • 文章目录一.urllib库基本介绍二.urllib.request 请求模块1.urlopen方法参数解析1.1.发送get请求1.2.发送post请求(设置data参数)1.3.设置timeout参数1.4.HTTPResponse对象2.构造Request对象三.urllib.parse URL解析...
  • 1. urllib.request模块模块定义了身份验证、重定向、cookies等应用中打开Url(主要是HTTP)的函数类。1)urlopen方法def urlopen(url, data=None, timeout=socket._GLOBAL_DEFAULT_TIMEOUT,*, cafile=None, capath=...
  • 1.urllib库 —内置 urlopen函数: 创建一个表示远程url的类文件对象,然后像本地文件一样操作这个类文件对象来获取远程数据。 url:请求的url。 data:请求的data,如果设置了这个值,那么将变成post请求。 返回值:...
  • Requests是用python语言基于urllib编写的,采用的是Apache2 Licensed开源协议的HTTP库如果你看过上篇文章关于urllib库的使用,你会发现,其实urllib还是非常不方便的,而Requests它会比urllib更加方便,可以节约我们...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 1,153
精华内容 461
关键字:

urllib库和requests库