十分钟入门爬虫框架scrapy

Posted python爱好部落

tags:

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

    我们在收集数据的时候,如果有一套爬虫模版,不需要写多少代码,该多好。市面上有这样一套框爬虫框架—Scrapy。Scrapy吸引人的地方在于它是一个框架,任何人都可以根据需求 方便的修改。它也提供了多种类型爬虫的基类,如BaseSpider、
sitemap爬虫等,最新版本又提供了web2.0爬虫的支持。

    Scrapy,发音如“西瓜皮”,当你使用后,你会发现爬虫如此简答。

    Scrapy是Python开发的一个快速,高层次的屏幕抓取和web抓取框架,用于抓取web站点并从页面中提取结构化的数据。Scrapy用途广泛,可以用于数据挖掘、监测和自动化测试。

  • 官方主页: http://www.scrapy.org/

  • 中文文档:Scrapy 0.25 文档

  • GitHub项目主页:https://github.com/scrapy/scrapy

原理我就不在这里讲了,文档上讲得够详细了。

安装scrapy

pip install Scrapy

创建一个scrapy项目

scrapy startproject testerhome
cd testerhome
    scrapy genspider example example.com

定义提取的item

获取名字,URL,以及网站的描述,在item中定义相应的字段。

编写spider

1.编写Spider类爬取到网页

自定义Spider时,需 继承scrapy.Spider类,且必须有以下三个成员:
name:用于区分不同的Spider,名字要唯一!!!
parse(response):Spider的一个回调函数,当Downloader返回Response时会被调用,
每个初始URL完成下载后生成的response对象将会作为唯一的参数传递
给该函数。该函数负责解析返回的数据(response),提取数据(生成item)
以及生成需要进一步处理的URL的Request对象。
start_requests():Spider刚启动时,生成需要爬去的链接,写这个
就不用写start_urls了。

2.取出网页中想要的信息

Scrapy中使用一种基于XPath和CSSDE表达式机制:Scrapy Selectors
来提取出网页中我们所需的数据。

Selector是一个选择,有四个基本方法:

  • xpath():传入xpath表达式,返回该表达式对应的所有节点的selector list列表;

  • css():传入CSS表达式,返回该表达式对应的所有及诶点的selector list列表;

  • extract():序列化该节点为unicode字符串并返回list;

  • re():根据传入的正则表达式对数据进行提取,返回unicode字符串list列表;

这里顺道学下XPath的基本语法:(更多可见:http://www.w3school.com.cn/xpath/)

首先XPath中的路径分为绝对路径与相对路径:
绝对路径:用/,表示从根节点开始选取;
相对路径:用//,表示选择任意位置的节点,而不考虑他们的位置;
另外可以使用*通配符来表示未知的元素;除此之外还有两个选取节点的:
.:选取当前节点;..:当前节点的父节点;

接着就是选择分支进行定位了,比如存在多个元素,想唯一定位,
可以使用[]中括号来选择分支,下标是从1开始算的哦!
比如可以有下面这些玩法:

  • /tr/td[1]:取第一个td

  • /tr/td[last()]:取最后一个td

  • /tr/td[last()-1]:取倒数第二个td

  • /tr/td[position()<3]:取第一个和第二个td

  • /tr/td[@class]:选取拥有class属性的td

  • /tr/td[@class='xxx']:选取拥有class属性为xxx的td

  • /tr/td[count>10]:选取 price 元素的值大于10的td

然后是选择属性,其实就是上面的这个@
可以使用多个属性定位,可以这样写:/tr/td[@class='xxx'][@value='yyy']
或者/tr/td[@class='xxx' and @value='yyy']

再接着是常用函数:除了上面的last(),position(),外还有:
contains(string1,string2):如果前后匹配返回True,不匹配返回False;
text():获取元素的文本内容
start-with():从起始位置匹配字符串
更多的自己去翻文档吧~

item piplie存储提取到的item

项目管道(Item Pipeline),负责处理有蜘蛛从网页中抽取的项目,他的主要任务是清晰、验证和存储数据。当页面被蜘蛛解析后,将被发送到项目管道,并经过几个特定的次序处理数据。

运行

得到我们的结果啦,最简单的存储数据的方式就是使用Feed exports,
支持四种导出格式:JSON,JSON lines,XML和CSV
使用也很简单,只是在平时执行scrapy脚本的后面加点东西:
可用命令
scrapy crawl spider名字  -o 导出文件名  -t 导出格式

好了,说了这么多,可能还是云里雾里,我们用通俗的例子来解释:
这里以楼盘项目来说明:
第一步:创建一个项目(开发商拍到地了,立项)
scrapy startproject
第二步:开始项目(审批通过,开始奠基)
scrapy genspider example example.com
第三步:提取的item(设计图纸,购买材料)
第四步:编写spider(开始建设)
第五步:Item Pipeline(交房)

好了,我们继续接上一次的网站testerhome来爬取,这次我想爬取精华页面的标题。
立项拍地
scrapy startproject testerhome

开始审批
scrapy genspider gettopic testerhome.com
然后就可以看到,项目下的组织结构了:

一行代码都没写,这就是框架的妙处。

提取的item(设计图纸,购买材料)

十分钟入门爬虫框架scrapy

定义一个title的字段,我只需要爬取这个。

编写spider(施工)
到spider这个路径下去,发现gettopic.py这个文件已经建立了
而且定义好了name,start_urls
我们现在只需要实现parse.主要就是把设计给实现了,现在我们只需要实现定义了一个titile.我们用浏览器自带的开发者工具获取。

十分钟入门爬虫框架scrapy

注意要定位准确,因为这个网站是框架式的,一不下心就能找到许多其它无关的。

import scrapy
from testerhome.items import TesterhomeItem

class GettopicSpider(scrapy.Spider):
    name = 'gettopic'
    allowed_domains = ['testerhome.com']
    start_urls = ['https://testerhome.com/topics/excellent']

    def parse(self,response):
        item = TesterhomeItem()
        item['title'] = response.xpath('//*[@id="main"]//div[@class="topics panel panel-default"]//div[2]/div[1]/a/text()').extract()
        yield item

运行(交房)

scrapy crawl gettopic -o test.csv

看到的结果是这样的:

如果我们想爬多个页面,可以这样来实现:

import scrapy

from testerhome.items import TesterhomeItem

class GettopicSpider(scrapy.Spider):
    name = 'gettopic'
    allowed_domains = ['testerhome.com']
    start_urls = ['https://testerhome.com/topics/excellent']

    def parse(self, response):
        base_url = 'https://testerhome.com/topics/excellent' + "?page={}"
        for page in range(2, 5):
            yield scrapy.Request(base_url.format(page), dont_filter=True, callback=self.parse_page)

    def parse_page(self, response):
        item = TesterhomeItem()
        item['title'] = response.xpath(
            '//*[@id="main"]//div[@class="topics panel panel-default"]//div[2]/div[1]/a/text()').extract()
        yield item

得到的结果就是多页的。

    

    我们十分钟就入了个门。Scrapy框架很强大,如果想深入了解,多读文档,多练习。

妈妈再也不用担心我不会写爬虫了。

以上是关于十分钟入门爬虫框架scrapy的主要内容,如果未能解决你的问题,请参考以下文章

转载教你分分钟学会用python爬虫框架Scrapy爬取心目中的女神

scrapy按顺序启动多个爬虫代码片段(python3)

scrapy主动退出爬虫的代码片段(python3)

SCRAPY爬虫框架入门实例

5分钟快速掌握 scrapy 爬虫框架

Python爬虫从入门到放弃之 Scrapy框架的架构和原理