scrapy分页抓取网页( ByShinChanPublished92014atglance)

优采云 发布时间: 2022-04-13 20:32

  scrapy分页抓取网页(

ByShinChanPublished92014atglance)

  Scrapy爬虫爬取网站数据

  由ShinChan

  2014 年 11 月 9 日出版

  内容

  一目了然

  Scrapy 是一个应用程序框架,用于抓取 网站 数据并提取结构化数据。它可以用于一系列程序,包括数据挖掘、信息处理或存储历史数据。

  它最初是为网页抓取(更准确地说,网页抓取)而设计的,但也可用于获取 API(例如 Amazon Associates Web 服务)或通用网络爬虫返回的数据。Scrapy 用途广泛,可用于数据挖掘、监控和自动化测试。

  Scrapy 使用 Twisted 异步网络库来处理网络通信。整体架构大致如下:

  

  Scrapy主要包括以下组件:

  使用Scrapy可以轻松完成在线数据的采集工作,它为我们做了很多工作,无需自己开发。

  Scrapy 教程

  在本文中,假设您已经安装了 Scrapy。如果没有,请参考。

  下面以爬取饮用水源BBS数据为例说明爬取过程。详情请参考 bbsdmoz 代码。

  本教程将带您完成以下任务:

  1. 创建一个Scrapy项目

2. 定义提取的Item

3. 编写爬取网站的 spider 并提取 Item

4. 编写 Item Pipeline 来存储提取到的Item(即数据)

  Scrapy 是用 Python 编写的。如果你是语言新手,对这门语言的特点和 Scrapy 的细节感到好奇,对于已经熟悉其他语言并想快速学习 Python 的编程老手,我们推荐 Learn Python The Hard Way,进行编程想要开始学习 Python 的初学者,非编程的 Python 学习资料列表供您选择。

  创建项目

  在开始抓取之前,您必须创建一个新的 Scrapy 项目。转到您打算存储代码的目录并运行以下命令:

  1

  scrapy startproject bbsdmoz

  此命令将创建具有以下内容的 bbsDmoz 目录:

  bbsDmoz/

scrapy.cfg

bbsDmoz/

__init__.py

items.py

pipelines.py

settings.py

spiders/

__init__.py

...

  这些文件是:

  定义我们的项目

  item是爬取数据的容器;它的用法类似于 python 字典,它提供了额外的保护来防止由拼写错误导致的未定义字段错误。

  与您在 ORM 中所做的类似,您可以通过创建一个 scrapy.Item 类并定义一个类型为 scrapy.Field 的类属性来定义一个 Item。(如果你不懂ORM,别担心,你会发现这一步很简单)

  首先根据从bbs网站获取的数据对item进行建模。我们需要从中获取 url、post board、poster 和 post 的内容。为此,请在 item.xml 中定义相应的字段。编辑 bbsDmoz 目录中的 items.py 文件:

  123456789101112

  # -*- coding: utf-8 -*-# Define here the models for your scraped items# See documentation in:# http://doc.scrapy.org/en/latest/topics/items.htmlfrom scrapy.item import Item, Fieldclass BbsDmozItem(Item): # define the fields for your item here like: # name = scrapy.Field() url = Field() forum = Field() poster = Field() content = Field()

  起初这可能看起来很复杂,但是通过定义一个项目,您可以轻松地使用其他 Scrapy 方法。而这些方法需要知道你的item的定义。

  我们的第一只蜘蛛

  蜘蛛是用户编写的类,用于从单个 网站(或某些 网站)中抓取数据。

  它包括一个用于下载的初始URL,如何跟踪网页中的链接以及如何分析页面中的内容,以及提取生成项目的方法。

  创建蜘蛛

  为了创建一个存储在 bbsDmoz/spiders 中的 Spider,您必须扩展 scrapy.Spider 类并定义以下三个属性:

  选择器选择器

  有很多方法可以从网页中提取数据。Scrapy 使用基于 XPath 和 CSS 表达式的机制:. 有关选择器和其他提取机制的信息,请参见此处。

  我们使用 XPath 选择要从页面的 HTML 源中提取的数据。以下是 XPath 表达式及其对应含义的示例:

  以饮水思源论坛首页为例:

  查看 HTML 页面源并为我们需要的数据(*敏*感*词*名称、描述和大小)创建一个 XPath 表达式。

  通过观察,我们可以发现poster是收录在pre/a标签中的,这里是userid=jasperstream:

  123

  ...[回复本文][原帖] 发信人: jasperstream

  所以可以提取jasperstream的XPath表达式为:

  1

  '//pre/a/text()'

  同理,我可以提取其他内容的XPath,提取后最好验证其正确性。以上只是几个简单的 XPath 示例,XPath 实际上远比这强大。如果您想了解更多信息,我们推荐此 XPath 教程。

  为了配合XPath,除了提供Selector之外,Scrapy还提供了避免每次从response中提取数据都生成selector的麻烦的方法。

  Selector 有四种基本方法(点击对应方法查看详细 API 文档):

  比如提取上面的poster数据:

  1

  sel.xpath('//pre/a/text()').extract()

  使用物品

  项目对象是自定义 python 字典。您可以使用标准字典语法来获取其每个字段的值(该字段是我们之前用 Field 分配的属性)。一般来说,爬虫会将爬取的数据作为Item对象返回。

  蜘蛛代码

  以下是我们的第一个蜘蛛代码,保存在 bbsDmoz/spiders 目录下的 forumSpider.py 文件中:

  1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950

  #-*- coding: utf-8 -*-'''bbsSpider, Created on Oct, 2014#version: 1.0#author: chenqx @http://chenqx.github.comSee more: http://doc.scrapy.org/en/latest/index.html'''from scrapy.selector import Selectorfrom scrapy.http import Requestfrom scrapy.contrib.spiders import CrawlSpiderfrom scrapy.contrib.loader import ItemLoaderfrom scrapy.contrib.linkextractors.sgml import SgmlLinkExtractorfrom bbs.items import BbsItemclass forumSpider(CrawlSpider): # name of spiders name = 'bbsSpider' allow_domain = ['bbs.sjtu.edu.cn'] start_urls = [ 'https://bbs.sjtu.edu.cn/bbsall' ] link_extractor = { 'page': SgmlLinkExtractor(allow = '/bbsdoc,board,\w+\.html$'), 'page_down': SgmlLinkExtractor(allow = '/bbsdoc,board,\w+,page,\d+\.html$'), 'content': SgmlLinkExtractor(allow = '/bbscon,board,\w+,file,M\.\d+\.A\.html$'), } _x_query = { 'page_content': '//pre/text()[2]', 'poster' : '//pre/a/text()', 'forum' : '//center/text()[2]', } def parse(self, response): for link in self.link_extractor['page'].extract_links(response): yield Request(url = link.url, callback=self.parse_page) def parse_page(self, response): for link in self.link_extractor['page_down'].extract_links(response): yield Request(url = link.url, callback=self.parse_page) for link in self.link_extractor['content'].extract_links(response): yield Request(url = link.url, callback=self.parse_content) def parse_content(self, response): bbsItem_loader = ItemLoader(item=BbsItem(), response = response) url = str(response.url) bbsItem_loader.add_value('url', url) bbsItem_loader.add_xpath('forum', self._x_query['forum']) bbsItem_loader.add_xpath('poster', self._x_query['poster']) bbsItem_loader.add_xpath('content', self._x_query['page_content']) return bbsItem_loader.load_item()

  定义项目管道

  在Spider中采集到Item后,会传递给Item Pipeline,一些组件会按照一定的顺序执行对Item的处理。

  每个项目管道组件(有时称为“项目管道”)都是一个实现简单方法的 Python 类。他们接收项目并对其执行一些操作,并且还决定该项目是继续通过管道还是被丢弃而不进行进一步处理。

  以下是item pipeline的一些典型应用:

  编写项目管道

  编写自己的项目管道很简单,每个项目管道组件都是一个单独的 Python 类,并且必须实现以下方法:

   process_item(item, spider)

  每个item pipeline组件都需要调用该方法,这个方法必须返回一个 Item (或任何继承类)对象,或是抛出 DropItem异常,被丢弃的item将不会被之后的pipeline组件所处理。

  参数:item (Item object) – 由 parse 方法返回的 Item 对象

     spider (Spider object) – 抓取到这个 Item 对象对应的爬虫对象

  此外,他们还可以实现以下方法:

  open_spider(spider)

  当spider被开启时,这个方法被调用。

  参数: spider (Spider object) – 被开启的spider

close_spider(spider)

  当spider被关闭时,这个方法被调用,可以再爬虫关闭后进行相应的数据处理。

  参数: spider (Spider object) – 被关闭的spider

  本文爬虫的item pipeline如下,保存为xml文件:

  12345678910111213141516171819202122232425262728293031

  # -*- coding: utf-8 -*-# Define your item pipelines here# Don't forget to add your pipeline to the ITEM_PIPELINES setting# See: http://doc.scrapy.org/en/latest/topics/item-pipeline.htmlfrom scrapy import signalsfrom scrapy import logfrom bbsDmoz.items import BbsDmozItemfrom twisted.enterprise import adbapifrom scrapy.contrib.exporter import XmlItemExporterfrom dataProcess import dataProcessclass XmlWritePipeline(object): def __init__(self): pass @classmethod def from_crawler(cls, crawler): pipeline = cls() crawler.signals.connect(pipeline.spider_opened, signals.spider_opened) crawler.signals.connect(pipeline.spider_closed, signals.spider_closed) return pipeline def spider_opened(self, spider): self.file = open('bbsData.xml', 'wb') self.expoter = XmlItemExporter(self.file) self.expoter.start_exporting() def spider_closed(self, spider): self.expoter.finish_exporting() self.file.close() # process the crawled data, define and call dataProcess function # dataProcess('bbsData.xml', 'text.txt') def process_item(self, item, spider): self.expoter.export_item(item) return item

  启用和设置项目管道

  为了启用 Item Pipeline 组件,您必须将其类添加到 ITEM_PIPELINES,如下例所示:

  123

  ITEM_PIPELINES = { 'bbsDmoz.pipelines.XmlWritePipeline': 1000,}

  分配给每个类的整数值决定了它们运行的​​顺序,项目按数字顺序从低到高,通过管道,这些数字通常定义在 0-1000 范围内。

  设置

  Scrapy 设置(settings)提供了一种自定义 Scrapy 组件的方法。您可以控制包括核心、扩展、管道和蜘蛛在内的组件。

  这些设置为代码提供了一个全局命名空间,可以从中提取键值映射配置值。可以通过下面描述的各种机制来设置设置。

  设置也是一种选择当前活动的 Scrapy 项目(如果你有多个)的方法。

  在设置配置文件中,可以指定抓拍的速率,是否在桌面显示抓拍进程信息等,具体请参考。

  该爬虫的设置配置如下:

  12345678910111213141516

  # -*- coding: utf-8 -*-# Scrapy settings for bbs project# For simplicity, this file contains only the most important settings by# default. All the other settings are documented here:# http://doc.scrapy.org/en/latest/topics/settings.htmlBOT_NAME = 'bbsDomz'CONCURRENT_REQUESTS = 200LOG_LEVEL = 'INFO'COOKIES_ENABLED = TrueRETRY_ENABLED = TrueSPIDER_MODULES = ['bbsDomz.spiders']NEWSPIDER_MODULE = 'bbsDomz.spiders'# JOBDIR = 'jobdir'ITEM_PIPELINES = { 'bbsDomz.pipelines.XmlWritePipeline': 1000,}

  爬行

  爬虫程序写好后,我们就可以运行程序来抓取数据了。进入项目 bbsDomz/ 的根目录,执行以下命令启动蜘蛛:

  1

  scrapy crawl bbsSpider

  这样您就可以等到程序完成运行。

  进一步阅读

0 个评论

要回复文章请先登录注册


官方客服QQ群

微信人工客服

QQ人工客服


线