| urllib是python的基本网络请求库,记得不用安装,直接import就可以用(如果记错,可百度下怎么安装,一般pip install xx),该模块下用过其两个类,一个是request类,用于请求,一个是parse类,用来解析编码之类,urllib库相对requests库(另一个模块),写起来更麻烦,一般能用requests库时,尽量使用requests,但也有些特别的。
from urllib import
request, parse # 导入模块,不用parse时,可以不导入parse类
request.urlopen() 简单的话,直接传入url发出请求,获取响应数据,返回的是类文件句柄对象,此类对象有read()、readline()、readlines()、getcode() 等方法。直接传入url这种做法,很多情况不能成功,因为很多网站有反爬虫机制,很容易被网站发现是爬虫,拒绝返回所需的数据,如果需要携带请求头数据,可用下面的request.Request类,传入请求头数据,再传给urlopen
resp = request.urlopen('http://www.baidu.com')
print(resp.read()) ------------------------------------------------
request.Request类
例:爬取拉勾网的数据(携带请求头,更好的伪装)
url =
'https://www.lagou.com/guangzhou-zhaopin/UIshejishi/?labelWords=label'
# 携带请求头数据,能更好伪装,User-Agent浏览器名称、referer引用
headers = {'User-Agent':'Mozilla/5.0
(Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko)
Chrome/75.0.3770.100 Safari/537.36', 'referer':'https://www.lagou.com/jobs/list_python?labelWords=&fromSearch=true&suginput='}
# 该请求为post请求,用字典数据类型,注意需要进行url编码和utf8编码
data = {
'first':'true',
'pn':1,
'kd':'python'
}
#
生成Request对象,传给urlopen,method为请求方式
req =
request.Request(url,headers=headers, data=parse.urlencode(data).encode('utf-8'),
method='POST')
resp = request.urlopen(req)
print(resp.read().decode('utf8'))
parse.urlencode()
如果发送的请求含查询条件,如百度搜索关键词时,url是这样子的
https://www.baidu.com/s? wd=刘德华
其中?号后面的这些就是查询字符串,要知道浏览器发送请求的url时,会自动将非英文非数字及某些符号外的字符进行十六进制的编码,要骗过服务器,那么也要对url所含字符进行编码处理,parse.urlencode() 就是进行url编码的,如
url = 'http://www.baidu.com/s'
params = {'wd':'刘德华'}
qs = parse.urlencode(params) # urlencode接收字典参数
url = url + '?' + qs # 拼接出百度搜索刘德华的url
resp = request.urlopen(url)
print(resp.read())
request.urlretrieve()
推荐这个,很好用!可方便以文件方式保存到本地,否则用with open
as之类,要写一堆代码,特别下载图片,如
resp = request.urlretrieve(img_url,
filename)
# 先备注一个好东西,os模块有个函数可以从字符串中分离出后缀名os.path.splitext()
# 如需要爬一堆图片,可以通过alt标签拿到文件名(除非不正规的网站),而图片的扩展名一般在img标签的src中,通过os.path.splitext(),可以从中分离出图片文件的扩展名,该方法返回的是类列表,可以用[1]拿到,这样可以拼接出图片的文件名filename
接下来的基本是鸡肋了,不过也先罗列一下,以备不时之需。
parse.parse_qs(),用于url解码,可对编码的url进行解码
parse.urlparse() 和parse.urlsplit(),可分割url,返回字典,通过key如scheme、netloc、path、params、query、fragment取协议(http、https等)、网址、路径、参数(指/s与?之间的参数)、查询字符串、fragment(这个不太清楚),urlsplit较urlparse,不能提取params
request.build_opener(),也是用于请求的,可以设置代理服务器、处理cookie,配合open方法发出请求,接受响应
1、使用代理服务器request.ProxyHandler()
为了隐藏真实ip或不被服务器发现爬虫程序,可使用代理ip或代理ip池,urllib使用代理,如
url =
'http://httpbin.org/ip'
# 使用ProxyHandler,传入代理构建handler
handler = request.ProxyHandler({'http':"223.241.78.43:8010"})
# 字典,http和https取决于代理
# 使用handler构建一个opener
opener = request.build_opener(handler)
# 使用opener.open() 发送一个请求
resp = opener.open(url)
print(resp.read())
2、处理cookie
Cookie是服务器发给客户端用于识别用户身份信息的数据,此外还有session,cookie和session的区别在于cookie是客户端保存的,而session是保存到服务器的,但不管是cookie还是session,在客户端都有相应的cookie,当客户端浏览器请求服务器时,会自动携带cookie信息给服务器,服务器进而识别用户身份,返回相应的数据给客户端浏览器。
当需要爬取需要用户登录才能访问的网站数据时,就要想办法携带cookie信息了。
方案一:将cookie放请求头,cookie可以在chrome network的request headers中拿到
方案二:用http.cookiejar模块,自动获取cookie
from urllib import
request,parse
from http.cookiejar import CookieJar
1、先携带登录用户名密码登录一次,cookie信息会保存到opener中
cookiejar=CookieJar() # 创建cookiejar对象
handler=request.HTTPCookieProcessor(cookiejar) # 创建HTTPCookieProcess对象
opener=request.build_opener(handler) # 使用handler创建opener
# 使用openr发送登录请求(携带登录的用户名和密码)
headers =
{'User-Agent':'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36
(KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36'}
data={
'email':"xxxxx@qq.com",
'password':'xxx'
}
login_url =
'http://www.renren.com/PLogin.do'
req =
request.Request(login_url, data=parse.urlencode(data).encode('utf-8'),
headers=headers)
# 只要登录即可,cookie信息会存入opener
opener.open(req)
2、再使用opener去请求登录后的页面,注意要用opener.open()
xx_url =
'http://www.renren.com/975132268/profile'
req =
request.Request(xx_url, headers=headers)
resp = opener.open(req)
with
open('renren.html','w',encoding='utf-8') as f:
f.write(resp.read().decode('utf-8'))
以上是关于urllib库的小结,下篇聊聊requests库,注意别混淆,urllib里面有request类,requests是一个独立的库,比urllib更强大,代码更简洁! |