scrapy初探:写一个简单的爬虫

来源:互联网 发布:大牛晒密软件 编辑:程序博客网 时间:2024/05/16 11:03

outline:
0 简介
1 工程的建立:
2 简单的爬虫
3 执行爬虫
4 文件下载
5 总结

0 简介
scrapy是一个爬虫框架。
该框架能够让我们集中在爬虫的核心处理上。但是,框架带来的缺点就是不够灵活。

1 工程的建立
前提:已经安装好python以及scrapy
在cmd中,进入相应的目录,使用命令:

scrapy startproject spider_name

得到目录如下:

spider_name/    scrapy.cfg    spider_name/        __init__.py        items.py        pipelines.py        settings.py        spiders/            __init__.py            ...

items.py:定义爬虫中的所有item。
spiders目录:要添加的代码目录。
scrapy.cfg:爬虫的配置文件。
pipelines.py:定义了爬虫的pipeline。

tips: Item是保存爬取的数据的一个容器;他的使用方法类似于python的字典。引用块内容

2 简单的爬虫
该小节写一个简单的爬虫demo。

<1> 在spiders目录里面添加一个py文件,当前定位myspider.py。这个文件就是当前爬虫的代码文件。

<2> 定义自己的Item,该Item继承自类scrapy.Item。在其中定义要保存的字段,该字段可以用scrapy.Field()初始化。该Item加载items.py中,当然也不是强制。

class MyItem(scrapy.Item):    url = scrapy.Field()    name = scrapy.Field()

代码中,定义了MyItem,其中要保存两个字段,一个是爬取的网页的URL,一个是爬取的网页的名字。

<3> 爬虫的主体,是要定义一个CrawlSpider的子类。这个类中定义了爬虫的动作。该类的主要属性有:
name: 定义了爬虫的名称,一个工程内,各个爬虫的名称不要重复。
allow_domains:定义了爬虫爬取网页允许的域名,是一个列表。
start_url:定义爬虫开始的URL,为一个列表。
rules:定义了爬虫遍历的链接的规则,为一个Rule类的列表。

在Rule类中,通常需要显示指定几个常用的参数:
LinkExtractor对象:接受allow,deny等参数,参数为正则表达式,表示要继续爬去的网页链接和拒绝的网页链接。
回调函数:使用字符串的形式传入回调函数的名称。不能使用parse作为回调函数,因为这个函数不能被重载。
follow参数:bool值,表示是否遍历。如果没有回调函数,该值默认为True。

另外两个中要的函数:
1> rules中的回调函数。
2 > parse_start_url: 该函数是需要改写的父类的函数。定义了在在start_url中的动作。

整个demo的代码如下:

# -*- coding -*-from scrapy.spiders import CrawlSpider, Rulefrom scrapy.linkextractors import LinkExtractorfrom scrapy.selector import Selectorfrom spider.items import MyItemclass MySpider(CrawlSpider):    name = 'MySpider'    allow_domains = ['douban.com']    start_urls = ['https://xxxxx.xxxxxx.com/chart/']    rules = [Rule(LinkExtractor(allow=[r'https://xxxxx.xxxxxx.com/subject/\d+/?$']), 'parse_it', follow=True)]    def parse_it(self, response):        myItem = MyItem()        myItem['url']= response.url        myItem['name'] = response.xpath("//title/text()").extract()        return myItem    def parse_start_url(self, response):        pass

这个demo中,只是简单的爬取网页的标题。在实际中,我们可以做更多的操作,比如统计网站中的数据,将网站中的图片下载下来等等。这些操作可以加载parse_start_url和parse_it这两个函数中。

3 执行爬虫
通过执行如下命令执行爬虫:

scrapy crawl MySpider

执行该命令需要进入到爬虫的目录中,第三个参数即为代码中定义的爬虫的名称。也可以将爬取的数据保存在文件中:

scrapy crawl MySpider -o items.json

每次要在命令行中切来切去的很烦,我们可以使用scrapy的cmdline, 在scrapy.cfg的同级目录下加入一个一个main.py如下,之后每次在pycharm中执行该脚本即可运行脚本。

# -*- coding:utf-8 -*-from scrapy import cmdlinecmdline.execute("scrapy crawl MySpider".split())

下面为爬取的json数据中的一部分:

[
[
{“url”: “https://xxxxx.xxxxxx.com/subject/26844922/“, “name”: [“\n \u6770\u51fa\u516c\u6c11\n”]},
{“url”: “https://xxxxx.xxxxxx.com/subject/26279289/“, “name”: [“\n \u6012\n”]},
{“url”: “https://xxxxx.xxxxxx.com/subject/25765735/“, “name”: [“\n \u91d1\u521a\u72fc3\uff1a\u6b8a\u6b7b\u4e00\u6218\n”]},
{“url”: “https://xxxxx.xxxxxx.com/subject/6873143/“, “name”: [“\n \u4e00\u6761\u72d7\u7684\u4f7f\u547d\n”]},
……
]

可以看到,爬取的内容即为Item中定义的内容。

有些网站可能使用了反爬虫机制,在这里,有一个简单的解决方法就是设置代理。在setting.py中加入设置如下:

USER_AGENT = 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_8_3) AppleWebKit/536.5 (KHTML, like Gecko) Chrome/19.0.1084.54 Safari/536.5'

4 文件下载
文件下载可以使用PIPELINE,常用的PIPELINE有FILESPIPELINE和IMAGEPIPELINE。在这个小节,以FILESPIPELINE来简单记录用法。

激活一个在setting.py中,pipeline需要有两步工作:
① 在配置项中激活pipeine。

ITEM_PIPELINES = {    'spider.pipelines.MyPipeline': 3,}

后面的数字是顺序,定义在1~1000内。

② 定义一个合法的目录。

FILES_STORE = '/pic'

这两个步骤都是必须的,一个没有配置好,就不会启动PIPELINE。

之后的工作,也就是最重要的工作就是定义PIPELINE类了。
在pipelines.py中定义自己的pipeline类,继承自类FILESPIPELINE。

在类中,主要需要实现的函数有两个。
process_item:每个item传递到pipeline中执行的操作。
item_completed:内容下载完成之后执行的操作,我们可以在这里执行重命名之类的动作。当然这个函数不是必须的,如果没有重命名的动作,下载下来的文件是以一个哈希码命名的。

下面是一个简单的demo:

class MyPipeline(FilesPipeline):    def process_item(self, item, spider):        for url in item["file_urls"]:            yield Request(url)    def item_completed(self, results, item, info):          pass

这里的file_urls需要在MySpider类中得到。为了方便的得到url,可以使用scrapy的选择器Selector。如下面的代码得到所有img标签中src字段带有.jpg的内容。

myItem['file_urls'] = Selector(text=response.body).xpath("//img[contains(@src, '.jpg')]/@src").extract()

有的时候,我们下载不下来内容,观察输出,会发现403错误。这是因为scrapy默认是遵循roberts协议的。在settings.py中加入以下配置,表示不遵守roberts协议。

ROBOTSTXT_OBEY = False

6 总结
scrapy是一个很方便快捷的爬虫框架,使用起来,只用关注url的正则表达式和一些关键动作代码就可以实现一个完整的爬虫。但是也牺牲了一定的灵活性。

1 0
原创粉丝点击