urllib的基本使用

写在前面的话上一篇文章我们利用Chrome浏览器及其自带的开发者工具对网络爬虫的抓包过程作了一些初步的分析,以下我们将正式开始使用Python提供的HTTP请求库urllib走入网络爬虫的大门

温馨提示 :博主使用的系统为Windows10,使用的Python版本为3.6.5
想要了解更规范的官方说明,可参考文档:https://docs.python.org/3.7/library/urllib.request.html

一、urllib简介

urllib是Python自带的HTTP请求库,无需复杂的安装下载即可正常使用,十分适合爬虫入门使用
urllib中包含四个模块,其中最常用的是request模块,用于发送HTTP请求

模块 描述
urllib.request HTTP请求模块
urllib.parse URL解析模块
urllib.error 异常处理模块
urllib.robotparser robots.txt解析模块

二、urllib初级使用

我们将通过urllib中最重要的一个函数 urllib.request.urlopen() 贯穿学习urllib的初级使用方法,我们会由浅入深的对此函数进行拓展,从而一步步的了解urllib的初级使用技巧,并且结合具体的例子讲解以便于对其有更好的理解

以下我们选择 http://www.httpbin.org/ 作为测试网站,它提供了丰富的接口,能返回所发送的请求的相关信息,例如 http://www.httpbin.org/get 返回的是我们所发送的get请求的相关信息,包括args、headers、origin、url等

1. urllib.request.urlopen(url)

urllib.request.urlopen() 最简单的一个用法就是给它传入一个 url 参数,url可以是一个字符串,代表目标网址的URL,另外值得注意的是,该函数返回的是一个 http.client.HTTPResponse 对象,而该对象有以下常用方法:

  • geturl():返回请求网站的URL
  • getcode():返回服务器的状态码
  • getheaders():返回的全部响应头信息
  • getheader(header):返回的指定响应头信息
  • read():得到的是网页源代码(bytees类型),通常需要配合使用 decode('utf-8') 将其转化为字符串类型
>>> import urllib.request

>>> response = urllib.request.urlopen("http://www.httpbin.org/get")

>>> type(response)     #查看response类型
<class 'http.client.HTTPResponse'>

>>> response.geturl()     #返回请求网站的URL
'http://www.httpbin.org/get'

>>> response.getcode()     #返回服务器的状态码
200

>>> response.getheaders()     #返回的全部响应头信息
[('Connection', 'close'), ('Server', 'gunicorn/19.9.0'), ('Date', 'Sat, 11 Aug 2018 01:39:14 GMT'), ('Content-Type', 'application/json'), ('Content-Length', '243'), ('Access-Control-Allow-Origin', '*'), ('Access-Control-Allow-Credentials', 'true'), ('Via', '1.1 vegur')]

>>> response.getheader('Connection')     #返回的指定响应头信息
'close'

>>> response.read()     #查看网页源代码(字节流类型)
b'{\n  "args": {}, \n  "headers": {\n    "Accept-Encoding": "identity", \n    "Connection": "close", \n    "Host": "www.httpbin.org", \n    "User-Agent": "Python-urllib/3.6"\n  }, \n  "origin": "116.16.107.180", \n  "url": "http://www.httpbin.org/get"\n}\n'

>>> response.read().decode('utf-8')     #查看网页源代码(字符串类型)
'{\n  "args": {}, \n  "headers": {\n    "Accept-Encoding": "identity", \n    "Connection": "close", \n    "Host": "www.httpbin.org", \n    "User-Agent": "Python-urllib/3.6"\n  }, \n  "origin": "116.16.107.180", \n  "url": "http://www.httpbin.org/get"\n}\n'

2. urllib.request.urlopen(url, data=None)

urllib.request.urlopen() 的第二个参数是 data ,当data参数没有被赋值时,则默认为None,使用GET请求方法发送请求(如上例),若希望使用POST方法发送请求时,则可以给data参数赋值,并在data中携带表单数据(bytes类型)

可以使用 urllib.parse.urlencode() 方法可以将字典类型转化成参字符串类型的表单数据

>>> import urllib.request
>>> import urllib.parse

>>> params = {
    'from':'AUTO',
    'to':'AUTO'
}
>>> data = urllib.parse.urlencode(params).encode('utf-8') 
>>> print(data)
b'from=AUTO&to=AUTO'

>>> response = urllib.request.urlopen('http://www.httpbin.org/post',data=data)
>>> print(response.read().decode('utf-8'))
{
  "args": {}, 
  "data": "", 
  "files": {}, 
  "form": {      #其中这个就是我们所设定的表单数据
    "from": "AUTO", 
    "to": "AUTO"
  }, 
  "headers": {
    "Accept-Encoding": "identity", 
    "Connection": "close", 
    "Content-Length": "17", 
    "Content-Type": "application/x-www-form-urlencoded", 
    "Host": "www.httpbin.org", 
    "User-Agent": "Python-urllib/3.6"
  }, 
  "json": null, 
  "origin": "116.16.107.180", 
  "url": "http://www.httpbin.org/post"
}

3. urllib.request.urlopen(req)

除了给 urllib.request.urlopen() 传入字符串表示URL之外,还可以传入一个 Request对象 来指定URL,此外,传入Request对象的另一个重要作用是便于指定请求头部

我们知道,在反爬虫中,服务器首先会检查请求头部中的 USER_AGENT 来检查该请求是否由网络爬虫程序发起,我们可以通过简单的修改 USER_AGENT 来绕过这一层检查,这里提供一个查找常用的 USER-AGENT 的网站:https://techblog.willshouse.com/2012/01/03/most-common-user-agents/

>>> import urllib.request

>>> url = 'http://www.httpbin.org/get'
>>> headers = {
    'User-Agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36'
}
#可以在参数data中指定携带的表单数据,在参数headers中指定携带的头部信息,在method指定发送请求的方法
>>> req = urllib.request.Request(url, data=None, headers=headers, method='GET')

>>> response = urllib.request.urlopen(req)
>>> print(response.read().decode('utf-8'))
{
  "args": {}, 
  "headers": {
    "Accept-Encoding": "identity", 
    "Connection": "close", 
    "Host": "www.httpbin.org", 
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36"     #其中这个就是我们设定的USER-AGENT
  }, 
  "origin": "116.16.107.180", 
  "url": "http://www.httpbin.org/get"
}

4. urllib.request.urlopen(url,data=None[,timeout])

urllib.request.urlopen() 的第三个参数是 timeout,用来指定等待时间,若超过指定时间还没获得响应,则抛出一个异常

我们可以使用urllib.error模块进行异常处理,其包含两个类:URLError和HTTPError,注意到HTTPError是URLError的子类,所以捕获异常时一般先要处理HTTPError异常,一般常用的格式如下:

import urllib.request
import urllib.error
import socket

>>> try:
    response = urllib.request.urlopen('http://www.httpbin.org/get', timeout=0.1)

#先处理HTTPError异常
except urllib.error.HTTPError as e:
    print("Error Code: %s\nError: %s" % (e.code,e.reason))

#再处理URLError异常
except urllib.error.URLError as e:
    if isinstance(e.reason, socket.timeout):
        print('Time out')

#若一切正常      
else:     
    print('Request Successfully')


Time out

三、urllib的高级用法

1. 使用代理

对于某些网站,若同一IP短时间内发送大量请求则可能会将该IP判定为爬虫,进而对该IP封禁,这样我们的爬虫就失效了,所以我们有必要使用随机的IP地址,这里提供几个提供免费IP地址的网站(但是必须要明确的一点是免费的代理IP十分不稳定):

西刺免费代理IP:http://www.xicidaili.com/nn/

云代理:http://www.ip3366.net/free/

快代理:https://www.kuaidaili.com/free/

注意,这些IP都是会随时更新的,所以最好自己写一个爬虫去维护,这里我们将会在以后讲到

>>> import urllib.request
>>> import random
>>> ip_list = [
    {'http':'61.135.217.7:80'},
    {'http':'59.32.37.112:61234'},
    {'https':'115.223.103.57:8010'}
]
>>> proxy_handler = urllib.request.ProxyHandler(random.choice(ip_list))
>>> opener = urllib.request.build_opener(proxy_handler)
>>> response = opener.open('http://www.httpbin.org/ip')
>>> print(response.read().decode('utf-8'))

2. 使用Cookie

(1)获取网站Cookie

>>> import urllib.request
>>> import http.cookiejar
>>> cookie = http.cookiejar.CookieJar()
>>> cookie_handler = urllib.request.HTTPCookieProcessor(cookie)
>>> opener = urllib.request.build_opener(cookie_handler)
>>> response = opener.open('http://www.baidu.com')
>>> for item in cookie:
        print(item.name+'='+item.value)  


BAIDUID=486AED46E7F22C0A7A16D9FE6E627846:FG=1
BDRCVFR[RbWYmTxDkZm]=mk3SLVN4HKm
BIDUPSID=486AED46E7F22C0A7A16D9FE6E627846
H_PS_PSSID=1464_21106_26920
PSTM=1533990197
BDSVRTM=0
BD_HOME=0
delPer=0

(2)使用Cookie模拟登陆

>>> import urllib.request
>>> import http.cookiejar

#将cookie保存到文件方便以后使用
>>> cookie = http.cookiejar.MozillaCookieJar('cookie.txt')     
>>> cookie_handler = urllib.request.HTTPCookieProcessor(cookie)
>>> opener = urllib.request.build_opener(cookie_handler)
>>> response = opener.open('http://www.baidu.com')
>>> cookie.save(ignore_discard=True,ignore_expires=True)
#此时在程序同目录下已经生成了'cookie.txt'文件

#从文件读取cookie用于模拟登陆
>>> cookie = http.cookiejar.MozillaCookieJar()
>>> cookie = cookie.load('cookie.txt',ignore_discard=True,ignore_expires=True)
>>> cookie_handler = urllib.request.HTTPCookieProcessor(cookie)
>>> opener = urllib.request.build_opener(cookie_handler)
>>> response = opener.open('http://www.baidu.com')
#此时登陆已经使用了保存的cookie信息了

写在后面的话 :经过上面的学习,我们已经初步了解了urllib使用的基本方法,下一篇文章我们将会使用urllib进行实战训练,谢谢大家

阅读更多
版权声明:本博客属于个人维护博客,未经博主允许不得转载其中文章。 https://blog.csdn.net/wsmrzx/article/details/81591558
文章标签: 网络爬虫 Python
个人分类: 网络爬虫
上一篇Chrome常用快捷键
下一篇用urllib实现有道翻译接口
想对作者说点什么? 我来说一句

python urllib使用PPT

2008年10月27日 114KB 下载

没有更多推荐了,返回首页

关闭
关闭
关闭