By 平常学python html
如下为我的在学习过程当中作的笔记总结之爬虫经常使用库urllibpython
urlib库为python3的HTTP内置请求库git
urilib的四个模块:github
urllib.request.urlopen(url,data=None,[timeout,]*,cafile=None,cadefault=False,context=None)浏览器
示例代码:markdown
1from urllib import request 2 3# 请求获取网页返回内容 4response = request.urlopen('https://movie.douban.com/') 5# 获取网页返回内容 6print(response.read().decode('utf-8')) 7# 获取状态码 8print(response.status) 9# 获取请求头 10print(response.getheaders())
1# 对请求头进行遍历 2for k, v in response.getheaders(): 3 print(k, '=', v)
可使用上面的代码对一些网站进行请求了,可是当须要一些反爬网站时,这就不行了,这时咱们须要适当地增长请求头进行请求,这时就须要使用复杂一点的代码了,这时咱们须要用到Request对象cookie
代码示例:python爬虫
1# 请求头 2headers = {'User-Agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.221 Safari/537.36 SE 2.X MetaSr 1.0'} 3requests = request.Request('https://movie.douban.com/', headers=headers) # 加入本身的请求头更加接近浏览器 4# 进行请求,把Request对象传入urlopen参数中 5response = request.urlopen(requests) 6print(response.read().decode('utf-8'))
这个我添加了请求头进行请求,使我发送的请求更加接近浏览器的行为。能够对应一些反爬网站了ide
若是网站须要进行登录,这时须要用到post方法,用上面的也是能够的。代码以下:post
1from urllib import request, parse 2# 使用post方法来进行模拟登录豆瓣 3data = {'source': 'None', 4 'redir': 'https://www.douban.com/', 5 'form_email': 'user', 6 'form_password': 'passwd', 7 'remember': 'on', 8 'login': '登陆'} 9# 将data的字典类型转换为get请求方式 10data = bytes(parse.urlencode(data), encoding='utf-8') 11requests = request.Request('https://accounts.douban.com/login', headers=headers, data=data, method='POST') 12response = request.urlopen(requests) 13print(response.read().decode('utf-8'))
这里我用到了data的参数把登录须要的参数传进去,还加了个请求方法Method
parse.urlencode()后面有讲
这里还有另一种添加请求头的方法
Request.add_header(): 参数有两个,分别为请求头对应的键和值,这种方法一次只能添加一个请****求头,添加多个须要用到循环或者直接用前面的方法添加多个请求头
在登录了网站以后,咱们须要用到cookie来保存登录信息,这时就须要获取cookie了。urllib获取cookie比较麻烦。
代码示例以下:
1from http import cookiejar 2# 获取cookie 3cookie = cookiejar.CookieJar() 4# 获取助手把cookie传进去 5handler = request.HTTPCookieProcessor(cookie) 6# 获取opener进行请求网站 7opener = request.build_opener(handler) 8# 请求网页 9response = opener.open('https://movie.douban.com/') 10# 打印cookie 11for c in cookie: 12 print(c.name, '=', c.value)
单纯地打印没什么用,咱们须要把他存入文件来保存,下次使用时再次加载cookie来登录
保存cookie为文件:
1from http import cookiejar 2# 将cookie保存在文件中 3filename = 'cookie.txt' 4cookie = cookiejar.MozillaCookieJar(filename) # 表示使用Mozilla的cookie方式存储和读取 5handler = request.HTTPCookieProcessor(cookie) 6opener = request.build_opener(handler) 7opener.open('https://movie.douban.com/') 8# 保存文件 9cookie.save(ignore_discard=True, ignore_expires=True)
另外一种保存方法:
1from http import cookiejar 2cookie = cookiejar.LWPCookieJar(filename) # 表示 Set-Cookie3 文件格式存储和读取 3handler = request.HTTPCookieProcessor(cookie) 4opener = request.build_opener(handler) 5opener.open('https://movie.douban.com/') 6# 保存文件 7cookie.save(ignore_discard=True, ignore_expires=True)
这两种保存格式都是不同的,须要保存的内容同样。
保存能够了,这时就须要用到加载了,固然也能够。代码以下:
1from http import cookiejar 2# 从cookie文件加载到网页上实现记住登录 3cookie = cookiejar.LWPCookieJar() 4# 加载文件 5cookie.load(filename, ignore_discard=True, ignore_expires=True) 6handler = request.HTTPCookieProcessor(cookie) 7opener = request.build_opener(handler) 8opener.open('https://movie.douban.com/')
这样就能够实现不用密码进行登录了。
cookie小总结:在操做cookie时,都是分五步,以下:
若是有时你在同一ip连续屡次发送请求,会有被封ip的可能,这时咱们还须要用到代理ip进行爬取,代码以下:
1proxy = request.ProxyHandler({ 2 'https': 'https://106.60.34.111:80' 3}) 4opener = request.build_opener(proxy) 5opener.open('https://movie.douban.com/', timeout=1)
能够看到越复杂的请求都须要用到request.build_opener(),这个方法有点重要,请记住哈
将上面的使用代理ip的请求进行异常处理,以下:
1from urllib import request, error 2try: 3 proxy = request.ProxyHandler({ 4 'https': 'https://106.60.34.111:80' 5 }) 6 opener = request.build_opener(proxy) 7 opener.open('https://movie.douban.com/', timeout=1) 8except error.HTTPError as e: 9 print(e.reason(), e.code(), e.headers()) 10except error.URLError as e: 11 print(e.reason)
由于有时这个ip或许也被封了,有可能会抛出异常,因此咱们为了让程序运行下去进而进行捕捉程序
解析url:urllib.parse.urlparse(url, scheme='', allow_fragments=True)
简单的使用:
1from urllib import request, parse 2# 解析url 3print(parse.urlparse('https://movie.douban.com/')) 4print(parse.urlparse('https://movie.douban.com/', scheme='http')) 5print(parse.urlparse('movie.douban.com/', scheme='http')) 6# 下面是结果 7ParseResult(scheme='https', netloc='movie.douban.com', path='/', params='', query='', fragment='') 8ParseResult(scheme='https', netloc='movie.douban.com', path='/', params='', query='', fragment='') 9ParseResult(scheme='http', netloc='', path='movie.douban.com/', params='', query='', fragment='')
能够看出加了scheme参数和没加的返回结果是有区别的。而当scheme协议加了,而前面的url也包含协议,通常会忽略后面的scheme参数
既而后解析url,那固然也有反解析url,就是把元素串连成一个url
1from urllib import parse 2# 将列表元素拼接成url 3url = ['http', 'www', 'baidu', 'com', 'dfdf', 'eddffa'] # 这里至少须要6个元素(我乱写的,请忽视) 4print(parse.urlunparse(url)) 5# 下面是结果 6http://www/baidu;com?dfdf#eddffa
urlparse()接收一个列表的参数,并且列表的长度是有要求的,是必须六个参数以上,要不会抛出异常
1Traceback (most recent call last): 2 File "E:/anaconda/python_project/python3_spider/urllib_test.py", line 107, in <module> 3 print(parse.urlunparse(url)) 4 File "E:\anaconda\lib\urllib\parse.py", line 454, in urlunparse 5 _coerce_args(*components)) 6ValueError: not enough values to unpack (expected 7, got 6)
urllib.parse.urljoin():这个是将第二个参数的url缺乏的部分用第一个参数的url补齐
1# 链接两个参数的url, 将第二个参数中缺的部分用第一个参数的补齐 2print(parse.urljoin('https://movie.douban.com/', 'index')) 3print(parse.urljoin('https://movie.douban.com/', 'https://accounts.douban.com/login')) 4# 下面是结果 5https://movie.douban.com/index 6https://accounts.douban.com/login
urllib.parse.urlencode():这个方法是将字典类型的参数转为请求为get方式的字符串
1data = {'name': 'sergiojuue', 'sex': 'boy'} 2data = parse.urlencode(data) 3print('https://accounts.douban.com/login'+data) 4# 下面是结果 5https://accounts.douban.com/loginname=sergiojuue&sex=boy
还有个urllib.robotparse库少用,就不说了,留给之后须要再去查文档吧。
上面的只是我在学习过程当中的总结,若是有什么错误的话,欢迎在留言区指出,还有就是须要查看更多用法的请查看文档https://docs.python.org/3/library/urllib.html
须要代码的能够去个人github上面fork,给个star也行!
github:https://github.com/SergioJune/gongzhonghao_code/blob/master/python3_spider/urllib_test.py
学习过程当中看的大可能是崔庆才大佬的视频:https://edu.hellobi.com/course/157