Python下用Scrapy和MongoDB构建爬虫系统(1)

本文由 伯乐在线 - 木羊 翻译,xianhu 校稿。未经许可,禁止转载!
英文出处:realpython.com。欢迎加入翻译小组

这篇文章将根据真实的兼职需求编写一个爬虫,用户想要一个Python程序从Stack Overflow抓取数据,获取新的问题(问题标题和URL)。抓取的数据应当存入MongoDB。值得注意的是,Stack Overflow已经提供了可用于读取同样数据的API。但是用户想要一个爬虫,那就给他一个爬虫。

像往常一样,在开始任何抓取工作前,一定要先查看该网站的使用/服务条款,要尊重 robots.txt 文件。抓取行为应该遵守道德,不要在很短时间内发起大量请求,从而导致网站遭受泛洪攻击。对待那些你要抓取的网站,要像对待自己的一样。

安装

我们需要Scrapy库(v0.24.4),以及用于在MongoDB中存储数据的PyMongo库(v2.7.2)。同样需要安装MongoDB。

Scrapy

如果使用OSX或某种Linux,使用pip安装Scrapy(激活命令行):


1

$ pip install Scrapy

如果使用Windows的机器,你需要手动安装一堆依赖库(木羊吐槽:Win下也是有pip的po主你不要黑她,经测可以用上面命令直接安装成功)。请参考官方文档详细说明以及我创建的Youtube视频。

一旦Scrapy安装完毕,可在Python命令行中使用这个命令验证:


1

2

>>> import scrapy

>>>

如果没有出错,安装就完成了。

PyMongo

下一步,使用pip安装PyMongo:


1

$ pip install pymongo

现在可以开始构建爬虫了。

Scrapy工程

先创建一个新的Scrapy工程:


1

$ scrapy startproject stack

这条命令创建了许多文件和文件夹,其中包含一套有助于你快速开始的基本模板:


1

2

3

4

5

6

7

8

├── scrapy.cfg

└── stack

    ├── __init__.py

    ├── items.py

    ├── pipelines.py

    ├── settings.py

    └── spiders

        └── __init__.py

提取数据

items.py文件用于定义存储“容器”,用来存储将要抓取的数据。

StackItem()类继承自Item (文档),主要包含一些Scrapy已经为我们创建好的预定义对象:


1

2

3

4

5

6

import scrapy

class StackItem(scrapy.Item):

    # define the fields for your item here like:

    # name = scrapy.Field()

    pass

添加一些想要收集的项。用户想要每条问题的标题和URL。那么,照这样更新items.py:


1

2

3

4

5

from scrapy.item import Item, Field

class StackItem(Item):

    title = Field()

    url = Field()

创建蜘蛛

在“spiders”目录下建立一个名为stack_spider.py的文件。这里是见证奇迹发生的地方—-比如在这里告诉Scrapy怎么去找到我们想要的指定数据。正如你想的那样,对于每一个独立的网页,stack_spider.py都是不同的。

我们从定义一个类开始,这个类继承Scrapy的Spider,并添加一些必须的属性:


1

2

3

4

5

6

7

8

9

from scrapy import Spider

class StackSpider(Spider):

    name = "stack"

    allowed_domains = ["stackoverflow.com"]

    start_urls = [

        "http://stackoverflow.com/questions?pagesize=50&sort=newest",

    ]

最初一些变量的含义很容易理解(文档):

  • 定义蜘蛛的名字。
  • allowed_domains 包含构成许可域的基础URL,供蜘蛛去爬。
  • start_urls 是一个URL列表,蜘蛛从这里开始爬。蜘蛛从start_urls中的URL下载数据,所有后续的URL将从这些数据中获取。

XPath选择器

接下来,Scrapy使用XPath选择器在一个网站上提取数据。也就是说,我们可以通过一个给定的XPath选择HTML数据的特定部分。正如Scrapy所称,“XPath是一种选择XML节点的语言,也可以用于HTML。”

使用Chrome的开发者工具,可以很容易找到一个特定的Xpath。简单地检查一个特定的HTML元素,复制XPath,然后修改(如有需要)。

开发者工具同时为用户提供在JavaScript控制台测试XPath选择器的功能,使用$x,如$x("//img"):

继续,通过定义的XPath告诉Scrapy去哪里寻找信息。在Chrom中导航至Stack Overflow网址,寻找XPath选择器。

右键点击第一条问题,选择“插入元素”:

现在从<div class="summary">, //*[@id="question-summary-27624141"]/div[2]中抓取XPath,然后在JavaScript控制台测试它:

也许你会说,这只选择了一条问题。现在需要改变XPath去抓取所有的问题。有什么想法?很简单://div[@class="summary"]/h3

什么意思呢?本质上,这条XPath是说:抓取<div>的子树中所有这一类<h3>元素的总集。在JavaScript控制台中测试XPath。

请注意我们不会使用Chrome开发者工具的实际输出。在大多数案例中,这些输出仅仅是一个参考,便于直接找到能用的XPath。

现在更新stack_spider.py脚本:


1

2

3

4

5

6

7

8

9

10

11

12

13

from scrapy import Spider

from scrapy.selector import Selector

class StackSpider(Spider):

    name = "stack"

    allowed_domains = ["stackoverflow.com"]

    start_urls = [

        "http://stackoverflow.com/questions?pagesize=50&sort=newest",

    ]

    def parse(self, response):

        questions = Selector(response).xpath(‘//div[@class="summary"]/h3‘)

提取数据

我们仍然需要解析和抓取想要的数据,它符合<div class="summary"&gt<h3&gt。继续,像这样更新stack_spider.py:


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

from scrapy import Spider

from scrapy.selector import Selector

from stack.items import StackItem

class StackSpider(Spider):

    name = "stack"

    allowed_domains = ["stackoverflow.com"]

    start_urls = [

        "http://stackoverflow.com/questions?pagesize=50&sort=newest",

    ]

    def parse(self, response):

        questions = Selector(response).xpath(‘//div[@class="summary"]/h3‘)

        for question in questions:

            item = StackItem()

            item[‘title‘] = question.xpath(

                ‘a[@class="question-hyperlink"]/text()‘).extract()[0]

            item[‘url‘] = question.xpath(

                ‘a[@class="question-hyperlink"]/@href‘).extract()[0]

            yield item

我们将遍历问题,从抓取的数据中分配标题和URL的值。一定要利用Chrome开发者工具的JavaScript控制台测试XPath的选择器,例如$x(‘//div[@class="summary"]/h3/a[@class="question-hyperlink"]/text()‘) 和$x(‘//div[@class="summary"]/h3/a[@class="question-hyperlink"]/@href‘)

测试

准备好第一次测试了吗?只要简单地在“stack”目录中运行下面命令:


1

$ scrapy crawl stack

随着Scrapy堆栈跟踪,你应该看到50条问题的标题和URL输出。你可以用下面这条小命令输出一个JSON文件:


1

$ scrapy crawl stack -o items.json -t json

我们已经基于要寻找的数据实现了爬虫。现在需要将抓取的数据存入MongoDB。

在MongoDB中存储数据

每当有一项返回,我们想验证数据,然后添加进一个Mongo集合。

第一步是创建一个我们计划用来保存所有抓取数据的数据库。打开settings.py,指定管道然后加入数据库设置:


1

2

3

4

5

6

ITEM_PIPELINES = [‘stack.pipelines.MongoDBPipeline‘, ]

MONGODB_SERVER = "localhost"

MONGODB_PORT = 27017

MONGODB_DB = "stackoverflow"

MONGODB_COLLECTION = "questions"

管道管理

我们建立了爬虫去抓取和解析HTML,而且已经设置了数据库配置。现在要在pipelines.py中通过一个管道连接两个部分。

连接数据库

首先,让我们定义一个函数去连接数据库:


1

2

3

4

5

6

7

8

9

10

11

12

13

14

import pymongo

from scrapy.conf import settings

class MongoDBPipeline(object):

    def __init__(self):

        connection = pymongo.Connection(

            settings[‘MONGODB_SERVER‘],

            settings[‘MONGODB_PORT‘]

        )

        db = connection[settings[‘MONGODB_DB‘]]

        self.collection = db[settings[‘MONGODB_COLLECTION‘]]

这里,我们创建一个类,MongoDBPipeline(),我们有一个构造函数初始化类,它定义Mongo的设置然后连接数据库。

处理数据

下一步,我们需要定义一个函数去处理被解析的数据:


1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

import pymongo

from scrapy.conf import settings

from scrapy.exceptions import DropItem

from scrapy import log

class MongoDBPipeline(object):

    def __init__(self):

        connection = pymongo.Connection(

            settings[‘MONGODB_SERVER‘],

            settings[‘MONGODB_PORT‘]

        )

        db = connection[settings[‘MONGODB_DB‘]]

        self.collection = db[settings[‘MONGODB_COLLECTION‘]]

    def process_item(self, item, spider):

        valid = True

        for data in item:

            if not data:

                valid = False

                raise DropItem("Missing {0}!".format(data))

        if valid:

            self.collection.insert(dict(item))

            log.msg("Question added to MongoDB database!",

                    level=log.DEBUG, spider=spider)

        return item

我们建立一个数据库连接,解包数据,然后将它存入数据库。现在再测试一次!

测试

再次,在“stack”目录下运行下面命令:


1

$ scrapy crawl stack

万岁!我们已经成功将我们爬下了的数据存入数据库:

总结

这是一个用Scrapy爬取网页的简单示例。真实兼职工作需要能跟踪分页链接的脚本,用CrawlSpider(文档)抓取每一个页面,非常容易实现。自己动手实现下,在下面Github仓库链接中写一个评论,快速查看代码。需要帮助?从这个脚本开始,它已经很接近完成了。然后查看第二部分,它包含完整的解决方案。

你可以从Github repo中下载完整的代码。如果有问题请跟贴评论。谢谢阅读!

时间: 2024-08-03 05:18:48

Python下用Scrapy和MongoDB构建爬虫系统(1)的相关文章

python应用:爬虫框架Scrapy系统学习第二篇——windows下安装scrapy

windows下安装scrapy 依次执行下列操作: pip install wheel pip install lxml pip install PyOpenssl 安装Microsoft visual c++ build tools pip install twisted 当此处提示错误时,安装Microsoft Visual C++ Compiler for Python 2.7 下载地址:https://www.microsoft.com/en-us/download/confirmat

利用scrapy和MongoDB来开发一个爬虫

今天我们利用scrapy框架来抓取Stack Overflow里面最新的问题(问题标题和网址),并且将这些问题保存到MongoDb当中,直接提供给客户进行查询. 安装 在进行今天的任务之前我们需要安装二个框架,分别是Scrapy (1.1.0)和pymongo (3.2.2). scrapy 如果你运行的的系统是osx或者linux,可以直接通过pip进行安装,而windows需要另外安装一些依赖,因为电脑的原因不对此进行讲解. $ pip install Scrapy 一旦安装完成之后你可以直

(转)python下很帅气的爬虫包 - Beautiful Soup 示例

官方文档地址:http://www.crummy.com/software/BeautifulSoup/bs4/doc/index.zh.html Beautiful Soup 相比其他的html解析有个非常重要的优势.html会被拆解为对象处理.全篇转化为字典和数组. 相比正则解析的爬虫,省略了学习正则的高成本. 相比xpath爬虫的解析,同样节约学习时间成本.虽然xpath已经简单点了.(爬虫框架Scrapy就是使用xpath) 安装 linux下可以执行 [plain] view plai

mac下python安装和scrapy安装

mac自带python和pip等工具,但是在使用安装scrapy时,报了一些错,因为对操作系统一些核心目录(比如/Library)没有可操作权限,mac有自己的一些权限控制程序(非sudo chmod能改变),所以干脆重新安装python,这样新安装的python就会在/usr目录里面,而不是系统自带的/Library下面./usr下面是我们有任何权限操作的. 1.我是利用homebrew的方法来安装,当然,也可以直接登录python官网下载安装,个人安装喜好. 2.执行brew install

Scrapy和MongoDB的应用---爬取

Scrapy是Python开发的一个快速.高层次的屏幕抓取和web抓取框架,用于抓取Web站点并从页面中提取结构化的数据.它最吸引人的地方在于任何人都可以根据需求方便的修改. MongoDB是现下非常流行的开源的非关系型数据库(NoSql),它是以“key-value”的形式存储数据的,在大数据量.高并发.弱事务方面都有很大的优势. 当Scrapy与MongoDB两者相碰撞会产生怎样的火花呢?与MongoDB两者相碰撞会产生怎样的火花呢?现在让我们做一个简单的爬取小说的TEST 1.安装Scra

Python中的Scrapy 命令相关用法

Python语言中Scrapy 命令是非常重要的一个命令,今天和大家分享的就是Scrapy 命令的相关用法.Scrapy 命令分为两种: 全局命令和项目命令,具体的用法,一起来看看吧 . 全局命令:在哪里都能使用. 项目命令:必须在爬虫项目里面才能使用. 全局命令 C:\\Users\\AOBO>scrapy -h Scrapy 1.2.1 - no active project Usage: scrapy[options] [args] Available commands: bench Ru

windows下安装Scrapy

前言 最近有一个爬虫的需求,其实之前也玩过一点,但是都只是止步于会用工具的程度,接下来准备深入系统学习一下python爬虫. 谈到python爬虫,不能不提的就是大名鼎鼎的scrapy爬虫框架.不过,如果只是入门的话,我建议没有必要过早的接触框架类的东西,尽量使用一些简单的工具库,会比较有助于你理解爬虫的原理. 只是我个人习惯,安装python之后就一定要把scrapy一起安装了,因为总觉得我迟早会用到它,所以先装着无妨. 之前安装scrapy时都是一路坎坷,没有那么容易,特别是在windows

Scrapy和MongoDB的应用

Scrapy是Python开发的一个快速.高层次的屏幕抓取和web抓取框架,用于抓取Web站点并从页面中提取结构化的数据.它最吸引人的地方在于任何人都可以根据需求方便的修改. MongoDB是现下非常流行的开源的非关系型数据库(NoSql),它是以“key-value”的形式存储数据的,在大数据量.高并发.弱事务方面都有很大的优势. 当Scrapy与MongoDB两者相碰撞会产生怎样的火花呢?与MongoDB两者相碰撞会产生怎样的火花呢?现在让我们做一个简单的爬取小说的TEST 1.安装Scra

Python实用工具包Scrapy安装教程

   对于想用每个想用Python开发网络爬虫的开发者来说,Scrapy无疑是一个极好的开源工具.今天安装之后觉得Scrapy的安装确实不易啊.所以在此博文一篇,往后来着少走弯路. 废话不多说了,如果你还不知道Scrapy是何物,可登陆在其官网http://scrapy.org/一览究竟,在此不再赘述. scrapy在国内目前使用的人比较少,除了他比较新以外,还在于他本身还有很多弊端,比如:需要的支持包比较多,这些支持包相互之间的依赖关系,导致人们在安装他的时候各种吐血,而且吐血了还不一定又正确