6

简介

scrapy爬虫这个东西我就不多做介绍了,总之是一个很好用的Python爬虫库,且关于scrapy也有较多的教程。这篇文章记录一下我个人的项目规划和天坑心得。

通常来说,我们执行了scrapy startproject example后就会创建这样的一个文件结构,大致如下:

├── example
│   ├── __init__.py
│   ├── __pycache__
│   ├── items.py
│   ├── middlewares.py
│   ├── pipelines.py
│   ├── settings.py
│   └── spiders
│       ├── __init__.py
│       └── __pycache__
└── scrapy.cfg

我们通常写爬虫都是在spiders里写爬虫解析规则,以及编写数据存储程序。

基础spider

我们首先来看爬虫程序,最基本是以下这个样子:

import scrapy
from sqlalchemy import distinct

class ExampleSpider(scrapy.Spider):
    name = 'example_spider'
    allowed_domains = []
    start_urls = [
            'https://www.example.com'
        ]
    def parse(self,response):
        pass

这样的一个基本爬虫,只要配置好start_urls,在这里写上我们想要去爬的URL,可以编写很多个,start_urls是一个数组。然后执行scrapy crawl example_spider就会自动去爬数据了。这里的parse方法是继承父类scrapy.Spider的解析方法,此处没有做任何结果解析以及存储。

在这个地方,其实我们要注意一点是,ExampleSpider这个类名我们可以瞎姬霸命名,我们在调用scrapy crawl [爬虫名]的时候,这个爬虫名是根据这个类里的name属性来的,此处的nameexample_spider,所以我们在执行的时候就是:scrapy crawl example_spider。当然在具体的编写过程中我个人建议是不要瞎姬霸命名,按照业务逻辑来。

再回头看我上面所展示的文件夹结构,随着业务的增长,我们很可能编写个成百上千的爬虫,那么每个爬虫都放到spiders一个文件夹里的话,要理清的话就要花大力气了,而实际上,在spiders其实可以创建任意的子文件夹进行逻辑上的分类,执行crawl的时候,会自动去遍历路径找到我们制定的爬虫,至于你编写了哪些爬虫,同样可以通过crapy list列出来。

分页爬技巧

分页爬虫技巧,其实在搜索引擎上都能找到,而且在segmentfault上都能搜到相应的解答,主要就在parse方法中判断条件或者说找到下一页的URL,然后用协程yield一下scrapy.Request就可以了,也就是用协程方式手动执行一下scrapy的Request方法,对于Request具体的返回,我没有深入看源代码研究,大概是在scrapy的底层再次做了一定的处理,实际的请求并不是Request类发起的。

常用配置

这里要结合一些原因来进行说明。

  • 通常来说,移动端的数据更好爬,我们可以用chrome的开发者工具模拟移动端浏览器,然后看移动端的数据交互形式以及移动端HTML数据格式。
  • 另外就是我们爬的时候通常为了防止被封IP,不能太频繁,一般是间隔1s钟去取一次数据这样子。

所以从上面两方面来说,我们在自己写的爬虫类中加上一个类属性download_delay,如

import scrapy
from sqlalchemy import distinct

class ExampleSpider(scrapy.Spider):
    download_delay = 1 # 1s钟发起一次请求,当前爬虫执行过程中,对任何位置的Reqeust都有效
    name = 'example_spider'
    allowed_domains = []
    start_urls = [
            'https://www.example.com'
        ]
    def parse(self,response):
        pass

另外就是在settings.py设置

DEFAULT_REQUEST_HEADERS = {
   'user-agent' : 'Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N)             AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3423.2 Mobile Safari/537.36'
}

一个这样的header头,模拟手机浏览器。

错入日志的重要性

在做爬虫的时候,非常重要的一点就是错误日志的记录,通常来说我们在settings.py中配置以下两个参数:

LOG_LEVEL = 'DEBUG'
LOG_FILE = './log.log' # 错误日志记录文件及路径

通常来说,我们最好是把LOG_LEVEL设置为DEBUG,也就是说,我们把所有的调试信息都输入到错误日志中进行记录,方便检查编写爬虫过程中可能出现的任何问题,尽可能的确保每个环节不出错。

如果没有意识到错误日志的重要性,在写爬虫的过程中只能抓瞎了,我是踩了好几次大坑才有过这种觉悟。

数据存储

数据存储,我个人用的是sqlalchemy,是一个很强大的库,我个人也做了些基础的封装,使用起来更方便。

数据存储一方面可能是在parse方法中进行解析后处理,另外的话,parse可以进行统一解析,然后在close进行全部批量存储,主要看具体的业务逻辑情况。

遇到过最坑爹的问题

最坑爹的问题就是要千万保证数据来源性的可靠,一定要反复对比其来源数据是否有问题,不然出现我们所医疗之外的数据情况,很可能找不到原因。

举个例子,我们在做分页处理的时候,已经到末尾页了,通常就可以判定结束爬虫了,但假设在某一个数据分类下,这个末尾页其实有个链接指向了其他分类页,然而在web浏览器中通过javascript程序禁止了跳转,然后就陷入了不断循环的取数据的过程中或者重复取了数据。当然这个是一个不太可能存在的可能情况,不过我在编写的过程中就遇到过类似的问题,在处理的时候千万要保证数据解析和来源数据的可靠性,切记切记!


kumfo
6.7k 声望4.1k 粉丝

程序生存法则: