Robots协议也称为爬虫协议,是网络爬虫排除标准(Robots Exclusion Protocol),用来告诉爬虫和搜索引擎哪些页面能够抓取,哪些不能够抓取。由于咱们若是无限制的使用爬虫爬取信息的话,且不说技术上可否突破某些网站上的发爬虫措施,若是毫无限制的进行爬取,再加上个分布式和多线程,则有可能致使把访问网站跑崩掉(虽然这种几率很小);可是这也说明了咱们须要对咱们的爬虫进行规范化处理,只能爬取咱们须要的别人愿意给的数据,这样就不会违反一些法律。
咱们能够在任何一个网站上加上/robots.txt
查看这个网站对于爬虫是否有限制,在这里举一个知乎的例子:https://www.zhihu.com/robots.txt
,出现的为下图:python
知乎里有User-agent与Disallow,Disallow 指定了不容许抓取的目录,而知乎里的意思就是禁止全部爬虫访问下面所列举的目录。git
咱们能够利用robotparser模块来解析robots.txt,robotparser 模块提供了一个类,叫作 RobotFileParser。它能够根据某网站的 robots.txt 文件来判断一个爬取爬虫是否有权限来爬取这个网页。github
urllib.robotparseR.RobotFileParser(url='') #只须要在构造方法中传入robots.txt的连接就能够了 #也能够是默认为空,而后使用set_url()方法进行设置。
咱们在利用urllib处理网页验证、处理cookies都是须要Opener、Handler来进行处理,可是requests库有着更为强大的用法。
urllib库的urlopen实际上也使以get的方式请求了一个网页,而在requests中咱们使用的直接就为get()方法。而其余类型相似post或者请求head都是能够直接用requests.post或者requests.head方法。json
r = requests.get(url,params=data,headers=headers)
这样请求的网址实际上为url+data,此外网页的返回类型若是是json格式,虽然返回的其实是str类型,可是是按照json的格式进行的,因此若是咱们想直接把返回结果解析获得一个字典格式的话,能够直接调用json()方法。经过这种方法,能够将返回结果是json格式的字符串转化成python中的字典形式。浏览器
利用requests能够模拟提交一些数据:cookie
import requests files={'file':open('favicon.ico','rb')} #文件必须和当前脚本在同一目录下 r=requests.post(url,files=files) print(r.text)
一样,能够利用requests下载文件:网络
import requests r = requests.get("https://github.com/favicon.ico") with open('favicon.ico', 'wb') as f: f.write(r.content)
比urillb会简单的许多,只需访问rrequests的cookies类型便可访问RequestsCookieJar:session
import requests r = requests.get('https://www.baidu.com') print(r.cookies) for key, value in r.cookies.items(): print(key + '=' + value)
咱们能够始终保持登陆的状态,将网页的cookies保存下来,再写入headers进行发送:多线程
import requests headers = { 'Cookie': 'q_c1=31653b264a074fc9a57816d1ea93ed8b|1474273938000|1474273938000; d_c0="AGDAs254kAqPTr6NW1U3XTLFzKhMPQ6H_nc=|1474273938"; __utmv=51854390.100-1|2=registration_date=20130902=1^3=entry_date=20130902=1;a_t="2.0AACAfbwdAAAXAAAAso0QWAAAgH28HQAAAGDAs254kAoXAAAAYQJVTQ4FCVgA360us8BAklzLYNEHUd6kmHtRQX5a6hiZxKCynnycerLQ3gIkoJLOCQ==";z_c0=Mi4wQUFDQWZid2RBQUFBWU1DemJuaVFDaGNBQUFCaEFsVk5EZ1VKV0FEZnJTNnp3RUNTWE10ZzBRZFIzcVNZZTFGQmZn|1474887858|64b4d4234a21de774c42c837fe0b672fdb5763b0', 'Host': 'www.zhihu.com', 'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.116 Safari/537.36', } r = requests.get('https://www.zhihu.com', headers=headers) print(r.text)
以前本身在作学校的信息门户信息爬取,可是每一次运行程序都抓不到数据,将错误信息答应出来发现是监测到有重复登陆的现象。明明是代码登录成功后而后继续get()去请求的,怎么会出错呢?
实际上,在requests用了几回get()或者其余方法,都至关于打开了一次新的浏览器,他们之间是彻底不相关的,因此并不存在第一个post()成功进行了模拟登陆,第二个get()是在成功模拟登陆的基础上继续进行操做,而是在打开一个浏览器进行新的操做,因此会出错。
解决方法是,在两次请求的时候都设置好同样的cookies,这样当然可行,可是很是繁琐,破坏了代码的简洁性。因此这里咱们须要维持同一个会话窗口,使用session对象。分布式
import requests s = requests.Session() s.get('http://httpbin.org/cookies/set/number/123456789') r = s.get('http://httpbin.org/cookies') print(r.text)
返回结果为:
{ "cookies": { "number": "123456789" } }
成功显示了咱们想要提交的cokies内容:number:123456789.