使用 Scrapy 构建一个网络爬虫
来自weixin
记得n年前项目需要一个灵活的爬虫工具,就组织了一个小团队用Java实现了一个爬虫框架,可以根据目标网站的结构、地址和需要的内容,做简单的配置开发,即可实现特定网站的爬虫功能。因为要考虑到各种特殊情形,开发还耗了不少人力。后来发现了Python下有这个Scrapy工具,瞬间觉得之前做的事情都白费了。对于一个普通的网络爬虫功能,Scrapy完全胜任,并把很多复杂的编程都包装好了。本文会介绍如何Scrapy构建一个简单的网络爬虫。
一个基本的爬虫工具,它应该具备以下几个功能:
通过HTTP(S)请求,下载网页信息
解析网页,抓取需要的内
保存内容
从现有页面中找到有效链接,从而继续抓取下一个网页

我们来看下Scrapy怎么做到这些功能的。首先准备Scrapy环境,你需要安装Python(本文使用v2.7)和pip,然后用pip来安装lxml和scrapy。个人强烈建议使用virtualenv来安装环境,这样不同的项目之间不会冲突。详细步骤这里就不赘述了。对于Mac用户要注意,当使用pip安装lxml时,会出现类似于的下面错误:
Error: #include “xml/xmlversion.h” not found
解决这个问题,你需要先安装Xcode的command line tools,具体的方法是在命令行执行下面的命令即可。
$ xcode-select --install
环境安装好之后,我们来用Scrapy实现一个简单的爬虫,抓取本博客网站的文章标题,地址和摘要。
1. 创建工程
$ scrapy startproject my_crawler
该命令会在当前目录下创建一个名为”my_crawler”的工程,工程的目录结构如下
my_crawler
|- my_crawler
| |- spiders
| | |- __init__.py
| |- items.py
| |- pipelines.py
| |- setting.py
|- scrapy.cfg
2. 设置待抓取内容的字段,本例中就是文章的标题,地址和摘要
修改”items.py”文件,在”MyCrawlerItem”类中加上如下代码:
# -*- coding: utf-8 -*-
import scrapy
class MyCrawlerItem(scrapy.Item):
title = scrapy.Field() # 文章标题
url = scrapy.Field() # 文章地址
summary = scrapy.Field() # 文章摘要
pass
3. 编写网页解析代码
在”my_crawler/spiders”目录下,创建一个名为”crawl_spider.py”文件(文件名可以任意取)。代码如下
# -*- coding: utf-8 -*-
import scrapy
from scrapy.linkextractors import LinkExtractor
from scrapy.spiders import CrawlSpider, Rule
from my_crawler.items import MyCrawlerItem
class MyCrawlSpider(CrawlSpider):
name = 'my_crawler' # Spider名,必须唯一,执行爬虫命令时使用
allowed_domains = ['bjhee.com'] # 限定允许爬的域名,可设置多个
start_urls = [
"http://www.bjhee.com", # 种子URL,可设置多个
]
rules = ( # 对应特定URL,设置解析函数,可设置多个
Rule(LinkExtractor(allow=r'/page/[0-9]+'), # 指定允许继续爬取的URL格式,支持正则
callback='parse_item', # 用于解析网页的回调函数名
follow=True
),
)
def parse_item(self, response):
# 通过XPath获取Dom元素
articles = response.xpath('//*[@id="main"]/ul/li')
for article in articles:
item = MyCrawlerItem()
item['title'] = article.xpath('h3[@class="entry-title"]/a/text()').extract()[0]
item['url'] = article.xpath('h3[@class="entry-title"]/a/@href').extract()[0]
item['summary'] = article.xpath('div[2]/p/text()').extract()[0]
yield item
对于XPath不熟悉的朋友,可以通过Chrome的debug工具获取元素的XPath。

4. 让我们测试下爬虫的效果
在命令行中输入:
$ scrapy crawl my_crawler
注意,这里的”my_crawler”就是你在”crawl_spider.py”文件中起的Spider名。
没过几秒钟,你就会看到要抓取的字段内容打印在控制台上了。就是这么神奇!Scrapy将HTTP(S)请求,内容下载,待抓取和已抓取的URL队列的管理都封装好了。你的主要工作基本上就是设置URL规则及编写解析的方法。
我们将抓取的内容保存为JSON文件:
$ scrapy crawl my_crawler -o my_crawler.json -t json
你可以在当前目录下,找到文件”my_crawler.json”,里面保存的就是我们要抓取的字段信息。(参数”-t json”可以省去)
5. 将结果保存到数据库
这里我们采用MongoDB,你需要先安装Python的MongoDB库”pymongo”。编辑”my_crawler”目录下的”pipelines.py”文件,在”MyCrawlerPipeline”类中加上如下代码:
# -*- coding: utf-8 -*-
import pymongo
from scrapy.conf import settings
from scrapy.exceptions import DropItem
class MyCrawlerPipeline(object):
def __init__(self):
# 设置MongoDB连接
connection = pymongo.Connection(
settings['MONGO_SERVER'],
settings['MONGO_PORT']
)
db = connection[settings['MONGO_DB']]
self.collection = db[settings['MONGO_COLLECTION']]
# 处理每个被抓取的MyCrawlerItem项
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)),使用upsert可以防止重复项
self.collection.update({'url': item['url']}, dict(item), upsert=True)
return item
再打开”my_crawler”目录下的”settings.py”文件,在文件末尾加上pipeline的设置:
ITEM_PIPELINES = {
'my_crawler.pipelines.MyCrawlerPipeline': 300, # 设置Pipeline,可以多个,值为执行优先级
}
# MongoDB连接信息
MONGO_SERVER = 'localhost'
MONGO_PORT = 27017
MONGO_DB = 'bjhee'
MONGO_COLLECTION = 'articles'
DOWNLOAD_DELAY=2 # 如果网络慢,可以适当加些延迟,单位是秒
6. 执行爬虫
$ scrapy crawl my_crawler
别忘了启动MongoDB并创建”bjhee”数据库哦。现在你可以在MongoDB里查询到记录了。

总结下,使用Scrapy来构建一个网络爬虫,你需要做的就是:
“items.py”中定义爬取字段
在”spiders”目录下创建你的爬虫,编写解析函数和规则
“pipelines.py”中对爬取后的结果做处理
“settings.py”设置必要的参数
其他的事情,Scrapy都帮你做了。下图就是Scrapy具体工作的流程。怎么样?开始写一个自己的爬虫吧。

本例中的代码可以在这里下载(http://www.bjhee.com/downloads/201511/my_crawler.tar.gz)。
使用 Scrapy 构建一个网络爬虫的更多相关文章
- 使用Scrapy构建一个网络爬虫
记得n年前项目需要一个灵活的爬虫工具,就组织了一个小团队用Java实现了一个爬虫框架,可以根据目标网站的结构.地址和需要的内容,做简单的配置开发,即可实现特定网站的爬虫功能.因为要考虑到各种特殊情形, ...
- 如何使用Scrapy框架实现网络爬虫
现在用下面这个案例来演示如果爬取安居客上面深圳的租房信息,我们采取这样策略,首先爬取所有租房信息的链接地址,然后再根据爬取的地址获取我们所需要的页面信息.访问次数多了,会被重定向到输入验证码页面,这个 ...
- Scrapy 轻松定制网络爬虫(转)
网络爬虫(Web Crawler, Spider)就是一个在网络上乱爬的机器人.当然它通常并不是一个实体的机器人,因为网络本身也是虚拟的东西,所以这个“机器人”其实也就是一段程序,并且它也不是乱爬,而 ...
- Python 网络爬虫 004 (编程) 如何编写一个网络爬虫,来下载(或叫:爬取)一个站点里的所有网页
爬取目标站点里所有的网页 使用的系统:Windows 10 64位 Python语言版本:Python 3.5.0 V 使用的编程Python的集成开发环境:PyCharm 2016 04 一 . 首 ...
- 构建一个给爬虫使用的代理IP池
做网络爬虫时,一般对代理IP的需求量比较大.因为在爬取网站信息的过程中,很多网站做了反爬虫策略,可能会对每个IP做频次控制.这样我们在爬取网站时就需要很多代理IP. 代理IP的获取,可以从以下几个途径 ...
- 使用Pycharm写一个网络爬虫
在初步了解网络爬虫之后,我们接下来就要动手运用Python来爬取网页了. 我们知道,网络爬虫应用一般分为两个步骤: 1.通过网页链接获取内容: 2.对获得的网页内容进行处理 这两个步骤需要分别使用不同 ...
- 用java语言构建一个网络服务器,实现客户端和服务器之间通信,实现客户端拥有独立线程,互不干扰
服务器: 1.与客户端的交流手段多是I/O流的方式 2.对接的方式是Socket套接字,套接字通过IP地址和端口号来建立连接 3.(曾经十分影响理解的点)服务器发出的输出流的所有信息都会成为客户端的输 ...
- python基础学习1-第一个网络爬虫程序
#!/usr/bin/env python # -*- coding:utf-8 -*- 煎蛋网抓妹子图 import urllib.request import os import random d ...
- 网络爬虫:使用Scrapy框架编写一个抓取书籍信息的爬虫服务
上周学习了BeautifulSoup的基础知识并用它完成了一个网络爬虫( 使用Beautiful Soup编写一个爬虫 系列随笔汇总 ), BeautifulSoup是一个非常流行的Python网 ...
随机推荐
- SILICA Xynergy-M4 Board -- STM32F417 meets XILINX Spartan-6
The SILICA Xynergy-M4 Board combines an ARM Cortex-M4 based STMicroelectronics STM32F417 controller ...
- 利用Jenkins实现JavaWeb项目的自动化部署
修改代码,打包,上传,重启... 大把的时间花费在这些重复无味的工作上.笔者与当前主流的价值观保持一致:我们应该把时间花费在更有意义的事情上.我们可以尝试借助一些工具,让这些重复机械的工作交给计算机去 ...
- [转载] 关于matlab GUI的一点心得
转载自 落落轻尘 [Fig文件方式,即使用菜单File->New->GUI来设计界面] 首先值得注意的是,在低版本matlab上制作的含GUI的m文件一般不能在高版本的matlab上面运行 ...
- 使用stream(流)实现多表数据传输
使用stream(流)实现多表数据传输 几乎所有的TCP和HTTP通信控件都支持stream(流)的传输. 使用stream(流)是可以实现多表数据传输的. 但这需要自定义协议了: 合并后的strea ...
- 【docker】 docker容器内部安装vi命令
有时会需要在docker容器内使用vi命令,但是新启动的docker容器内并没有vi命令,那就需要自己安装一个 1.使用命令 apt-get update 2.进行安装 apt-get install ...
- html在线编辑器汇总
1. TinyMCE 免费,开源,轻量的在线编辑器,基于 JavaScript,高度可定制,跨平台. 2. FCKEditor 免费,开源,用户量庞大的在线编辑器,有良好的社区支持. 3. YUI E ...
- Spring3.1.2与Hibernate4.1.8整合
整合Spring3.1.2 与 Hibernate 4.1.8 首先准备整合jar: Spring3.1.2: org.springframework.aop-3.1.2.RELEASE.jar or ...
- 转: 用 Go 写一个轻量级的 ldap 测试工具
前言 这是一个轮子. 作为一个在高校里混的 IT,LDAP 我们其实都蛮熟悉的,因为在高校中使用 LDAP 来做统一认证还蛮普遍的.对于 LDAP 的管理员而言,LDAP 的各种操作自然有产品对应的管 ...
- opencv编译Python接口
cmake-gui 配置 确认这些都正确 生成了CV2.so make install cv2.__version__ '3.0.0'
- Flask 学习(三)模板
Flask 学习(三)模板 Flask 为你配置 Jinja2 模板引擎.使用 render_template() 方法可以渲染模板,只需提供模板名称和需要作为参数传递给模板的变量就可简单执行. 至于 ...