python爬虫框架之scrapy的快速上手

下载与安装

pip install scrapy

创建项目

scrapy startproject 项目名称

这里我们指定的项目名称为Spider,执行完创建项目的命令后,得到的提示为:

You can start your first spider with:
      cd Spider
      scrapy genspider example example.com

然后按照提示,依次来执行这两行命令。
这里,cd命令是切换到当前爬虫的工作目录。
genspider 则是生成一个爬虫,该爬虫的名字为example,要爬取的网站为example.com。
当然,example和example.com 可以根据实际情况进行修改。

执行完生成爬虫的命令后,我们可以看到如下提示:

Created spider 'example' using template 'basic' in module:
  Spider.spiders.example

从提示中可以看到,这里使用了‘basic’模板来生成爬虫,当然可以指定别的模板
关于另一个模板-crawl请见https://www.cnblogs.com/ASE265/p/12363843.html
最终,我们得到的这整个项目的框架为:

Spider
    spiders
        _init_.py
        example.py
    _init_.py
    items.py
    middleswares.py
    pipelines.py
    settings.py
scrapy.cfg

这些文件分别是:

  • scrapy.cfg:项目配置的文件
  • Spider:该项目的python模块,该文件夹的名字为startproject命令指定的名字
  • items.py:项目的item文件
  • pipilines.py:项目的管道文件
  • settings.py:项目的设置文件
  • spiders:放置爬虫代码的文件夹
  • spiders/example.py:爬虫文件

example.py文件

不同的模板生成的文件是不一样的,这里的example.py文件对应于‘basic’模板。

# -*- coding: utf-8 -*-
import scrapy

class ExampleSpider(scrapy.Spider):
    name = 'example'
    allowed_domains = ['example.com']
    start_urls = ['http://example.com/']

    def parse(self, response):
        pass

可以看到,该文件定义了一个爬虫类ExampleSpider,它继承于Spider类,各个属性和方法的定义如下:

  • name:爬虫的名字,定义了Scrapy如何定义并初始化spider,非常重要的属性
  • allowed_domains:指定允许爬取的域名列表
  • start_url:当没有指定特定的URL时,爬虫将从该列表中开始进行爬取 另:在start_url中的url不属于指定URL
  • parse函数:则是对请求start_url返回的response对象进行分析,该函数需要用户自定义。

至于怎么根据start_url来发出请求我们实际上并不用关心
事实上,Scrapy是有意对其进行了封装
Spider类有一个start_requests()方法
该方法的默认实现是使用 start_urls 的url生成Request
可对该方法进行重写,但大可不必

Spider类还提供了一个make_requests_from_url(url)方法,
当spider启动爬取并指定了URL时,make_requests_from_url()将被调用来创建Request对象
该方法接受一个URL并返回用于爬取的Request对象,也可以对该方法进行重写
另:在看源码的时候发现该方法已被弃用,以后的版本将不再使用该方法

例子:新浪新闻的简单爬取

这里,假设我们已经对新浪新闻网站进行了分析,并决定爬取新浪新闻里的滚动新闻里的国内新闻版块。
为了不与之前的example搞混,我们根据上述的流程重新创建一个用于爬取新浪新闻的爬虫。
具体实现的功能是爬取共爬取10页的所有新闻链接,然后再根据得到的新闻链接爬取对应的新闻
并将新闻的标题,内容和发布时间等信息保存下来。

因此,在我们的爬虫文件中,设置的参数如下:

name = 'sina'
allowed_domains = ['feed.mix.sina.com.cn','sina.com.cn']
start_urls = ["https://feed.mix.sina.com.cn/api/roll/get?pageid=153&lid=2510&k=&num=50&page={}".format(page) for page in range(10)]

然后,决定我们需要爬取的内容
比如我们需要获得每篇文章的标题,关键字,内容,发布的时间,媒体,标签这些内容
因而需要对items.py文件进行设置,设置内容如下:

import scrapy

class SinaItem(scrapy.Item):
    # define the fields for your item here like:
    # name = scrapy.Field()
    title= scrapy.Field()
    keywords = scrapy.Field()
    time= scrapy.Field()
    media = scrapy.Field()
    content = scrapy.Field()
    tag= scrapy.Field()
    pass

然后,回到我们的爬虫文件,将items.py的内容导入到爬虫文件中
from Sina.items import SinaItem

parse函数的一个参数为:response
它是对start_url请求后获得的一个response对象,就是包含了请求的网页的信息
在这里,parse函数实现为:
在response中依次提取url,并将其抛给parsecontent函数
由parsecontent函数来处理请求该url后获得的response的内容。

def parse(self, response):
    result = response.text
    data = json.loads(result).get('result').get('data')
    for news in data:
        url = news.get('url')
        yield scrapy.Request(url, callback=self.parsecontents)

parseconten函数的内容为根据请求url后返回的response内容进行提取
另:使用xpath对网页格式的内容提取非常方便,推荐使用

def parsecontents(self,response):
    title = response.xpath('//title/text()').extract()[0]
    meta = response.xpath('//meta/@content').extract()
    keywords = meta[2]
    time = meta[10]
    media = meta[13]
    paragraph = response.xpath('//div[@class="article"]/p/text()').extract()
    content = ""
    for p in paragraph:
        content = content + p
    item = SinaItem()
    item['title'] = str(title)
    item['keywords'] = str(keywords)
    item['time'] = str(time)
    item['media'] = str(media)
    item['content'] = str(content)
    item['tag'] = "news"
    yield item

爬虫运行

在工作目录下输入命令以启动爬虫

scrapy crawl 爬虫名称

这里输入的命令为:scrapy crawl sina

内容保存

爬虫爬取的内容保存实现在pipelines.py文件,在编写爬虫时,我们最后抛出了item。
这个item最后被传送得到了pipelines.py中
在pipelines.py文件中,我们可以实现将获取的item写入文件或者保存得到MongoDB数据库中。

爬虫结果

爬取得到的内容为:

爬取结束后,scrapy会给出统计信息

代码

具体代码,请见github

原文地址:https://www.cnblogs.com/ASE265/p/12214364.html