使用python制作爬虫

整理scrapy爬虫

python爬虫的教程在网络上特别多,我这里再出教程就很多余。所以我将我个人使用python制作爬虫的心得整理一下。
整理也是学习的一种方法。

我主要使用的框架是scrapy,scrapy非常强大,满足工作的所有需求。其他的爬虫框架,我接触不多。这里不做比对。

我们先从scrapy的一张图说起。
=w400

  1. 启动Spider爬虫,通过配置start_urls或者start_request
  2. 实际请求通过scrapy引擎将请求送到了Scheduller调度器,然后由它负责去和网络做请求。
  3. 请求的响应,被Spider的下载器Downloader处理。然后处理的结果由于scrapy引擎返回给了Spider爬虫。就是常用的parse函数。
  4. 这些数据需要被存到本地文件,数据库中,因此又会出现ItemPipleline,parse返回的结果又被ItemPipleline处理。

这一通操作就是scrapy的基本流程。中间件几乎不用配置,就能基本跑起来。但是深层次的爬虫后期还是需要配置中间件。

基本操作

命令行

1
2
3
4
5
6
7
8
9
scrapy genspider -l #查看爬虫模板。
scrapy shell "http://www.cnblogs.com/"
scrapy shell -s USER_AGENT="123123daili" 网站地址 #以代理的方式请求网址。这个方式非常有用。
response.json() #以json查看请求结果
response.xpath(xpath的规则)
view(response) #在浏览器中查看请求结果。如果这里看的结果和你在浏览器里面看的结果一样。那这个网站差不多没有异步请求。如果不一样,就要检查是不是有异步请求。

req = scrapy.Request("想要爬的网址")
req.meta["proxy"] = "设置你的代理"

代理这里最好不要用免费的代理,非常坑爹。付费代理也很坑爹。经常出现乱扣费的现象。如大家有稳定的信用比较好的代理,还请推荐一下。

为什么提到命令行,因为很多情况下,我们不必要创建工程,直接用命令行就能快速验证问题。非常方便。

基本流程

scrapy genspider -l 能显示4种模板,但是常用的只有basic,crawl两种。

创建工程命令scrapy startproject 爬虫名称 网站地址
创建的就是basic类型的爬虫。scrapy genspider -t crawl 爬虫名称 网站地址
crawl爬虫是抓取页面上所有的链接。我们需要对链接设定规则,把想要的链接抓取出来。然后抓取这一个链接下的页面信息。相对的,basic就是之抓取一个页面的信息。
所以crawl爬虫继承自baisc爬虫。

一般情况下爬取到的内容,我们可以直接xpath,css等方法就可以解析出来。
但是现在很多网站都做了反爬虫机制,页面是异步加载。
怎么判断页面是否异步加载?
一个简单的方法就是在命令行中,先fetch这个页面,然后view(response),这样本地浏览器会自动代开刚刚你请求的页面结果。如果页面上出现很多空白,显示没有加载出来的地方。那就是异步加载了。
异步加载的抓取,我们可以通过浏览器开发者工具,自己追踪查找,把请求找出来。接下来就可以自己用爬虫请求了。
但是如果是大批量的请求,这种方式就不靠谱了。这时候就开始用上Selenium神器了。可以模拟浏览器的行为。想要了解更多的同学可以自行搜索。

内容抓取出来了,接下来就是存储了。excel,文本,数据库都可以。
我们生成Spider的工程时,下面有一个pipeline.py的模块。它里面放了一个处理数据的对象。比如我这里的一个文件。

1
2
3
4
5
6
7
8
class DoubanSpPipeline(object):
def __init__(self):
self._client = pymongo.MongoClient("mongodb://localhost:27017/")
self._db = self._client.scrapy_db
self._collection = self._db.douban_col
def process_item(self, item, spider):
self._collection.insert({"url":item["url"],"title":item["title"]})
return item

DoubanSpPipeline在项目启动的时候,被实例化一次。然后被Spide引擎调用process_item来存储数据。
我这里使用的是mongodb数据库。就这么几行代码,就可以将我抓取的豆瓣数据全部存到本地。

问题

上述流程,能简单的抓一些页面。但是现在网站的运维同学都相当厉害,绝不会轻易让你抓取到他所有的页面。因此出现反爬虫,反反爬虫。
这个历史就很有意思了。
总之我们为了能伪装成用户,绕过网站的阻拦,直接访问到内容还有以下路要走。

  1. 常用设置代理。代理上面提到了。最好的代理方式是自己维护一个代理池。从那些代理网站上抓取免费,使用代理的时候能够先验证一下,是否有效。在交给爬虫请求。
  2. user-agent。常用的都是浏览器ua,不过有人提到使用手机app的UA,比较不容易被封。这里也可以通过中间件UserAgentMiddleware的方法process_request设置request.headers[‘User-Agent’] = “你的ua”
  3. 登录。网站发现你频繁的请求,不会封你,当时会让redirect到登录。这个时候爬虫级不工作了,所以我们得在response中检查是否是要登录了。然后自己写代码去登录。用户名,密码发过去。但是还是不通过。原来人家登录请求还额外附带了别的参数。真是防不胜防。登录之后,将cookie保存,然后所有的请求都增加这个cookie值。
  4. 分布式爬虫。scrapy-redis.

学习资料

网站关于爬虫的资料很多。很多都是重复的。如果大家真要学习爬虫,最好自己先把环境一搭,弄个简单的工程。就大致明白了。
查文档网站:https://scrapy-cookbook.readthedocs.io/zh_CN/latest
查文档网站:https://scrapy-cookbook.readthedocs.io/zh_CN/latest
scrapy cookbook:https://scrapy-cookbook.readthedocs.io/zh_CN/latest/