Python网络爬虫

Posted 南云之苑

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Python网络爬虫相关的知识,希望对你有一定的参考价值。

关于Robots协议

Robots协议也称为爬虫协议,是网络爬虫排除标准(Robots Exclusion Protocol),用来告诉爬虫和搜索引擎哪些页面可以抓取,哪些不可以抓取。因为我们如果无限制的使用爬虫爬取信息的话,且不说技术上能否突破某些网站上的发爬虫措施,如果毫无限制的进行爬取,再加上个分布式和多线程,则有可能导致把访问网站跑崩掉(虽然这种概率很小);但是这也说明了我们需要对我们的爬虫进行规范化处理,只能爬取我们需要的别人愿意给的数据,这样就不会违反一些法律。
我们可以在任何一个网站上加上/robots.txt查看这个网站对于爬虫是否有限制,在这里举一个知乎的例子:https://www.zhihu.com/robots.txt,出现的为下图:

知乎里有User-agent与Disallow,Disallow 指定了不允许抓取的目录,而知乎里的意思就是禁止所有爬虫访问下面所列举的目录。

urllib的robotparser

我们可以利用robotparser模块来解析robots.txt,robotparser 模块提供了一个类,叫做 RobotFileParser。它可以根据某网站的 robots.txt 文件来判断一个爬取爬虫是否有权限来爬取这个网页。

urllib.robotparseR.RobotFileParser(url='')
#只需要在构造方法中传入robots.txt的链接就可以了
#也可以是默认为空,然后使用set_url()方法进行设置。

关于Requests

我们在利用urllib处理网页验证、处理cookies都是需要Opener、Handler来进行处理,但是requests库有着更为强大的用法。
urllib库的urlopen实际上也使以get的方式请求了一个网页,而在requests中我们使用的直接就为get()方法。而其他类型类似post或者请求head都是可以直接用requests.post或者requests.head方法。

GET请求

r = requests.get(url,params=data,headers=headers)
这样请求的网址实际上为url+data,此外网页的返回类型如果是json格式,虽然返回的实际上是str类型,但是是按照json的格式进行的,所以如果我们想直接把返回结果解析得到一个字典格式的话,可以直接调用json()方法。通过这种方法,可以将返回结果是json格式的字符串转化成python中的字典形式。

文件上传与下载

利用requests可以模拟提交一些数据:

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)

Cookies

比urillb会简单的许多,只需访问rrequests的cookies类型即可访问RequestsCookieJar:

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.

以上是关于Python网络爬虫的主要内容,如果未能解决你的问题,请参考以下文章

python网络爬虫

学习《从零开始学Python网络爬虫》PDF+源代码+《精通Scrapy网络爬虫》PDF

Python网络爬虫学习手记——爬虫基础

python网络爬虫入门

网络爬虫开发实战2和一的区别

手把手教你利用爬虫爬网页(Python代码)