网页爬虫--scrapy入门
本篇从实际出发,展示如何用网页爬虫。并介绍一个流行的爬虫框架~
1. 网页爬虫的过程
所谓网页爬虫,就是模拟浏览器的行为访问网站,从而获得网页信息的程序。正因为是程序,所以获得网页的速度可以轻易超过单身多年的手速:)。通常适用于需要大量网页信息的场合。
爬取网页的流程为:访问初始url -> 获得返回的网页,从这个网页中得到新的url并放入待爬队列 -> 访问新的url-> ...依次循环。整体上来看就是一个广度优先的过程,当然,新的url也不一定非要从返回的网页中获得。
一个简单的网页爬虫应该包括以下部分:
- 一个url队列。我们的爬虫从这个队列中读取url,并将新的url放入这个队列。这里最重要的是判重。简单的哈希就能达到判重的目的,但是为了节约空间(url的数量往往很多),一般使用bloomfilter的思想。bloomfilter与普通的哈希算法最大的不同就是bloomfilter只需要一个bit来表示某个元素是否存在,所以能节约空间。bloomfilter有一个小缺点,即准确率并不是百分百:判断一个元素是不是已经存在时,已有的有很小的可能会判断为不存在,但是没有的元素一定会判断为不存在。
- 网页爬取模块。需要能模拟浏览器发送请求。
- 网页分析模块。爬下来的是网页源码,可以用正则或者其他方法提取我们需要的信息。
- 新的url生成模块。生成新的url,放入队列。
那么,最简单的爬虫就可以这么写:
import Queue
start_url = "http://www.cnblogs.com/rubinorth"
url_queue = Queue.Queue() # url队列
url_queue.put(start_url)
bloomfilter.put(start_url)
#### 一直循环到队列为空 ####
while(True):
if url_queue.size() > 0:
current_url = url_queue.get() # 队首的url
page = crawl(current_url) # crawl为网页爬取模块,page是爬到的网页源代码
next_urls = deal_page(page) # deal_page为网页分析模块,next_urls是新的一些url
for next_url in next_urls:
if not bloomfilter.has(next_url): # 判重
bloomfilter.put(next_url)
url_queue.put(next_url)
else:
break
2. 为什么选用scrapy
scrapy是目前一个比较流行的爬虫框架,其基本原理与上面的爬虫是一样的,但是它提供了很多便利的功能。
首先,先简要介绍一下scrapy各个模块之间的关系和整个框架运行的流程。是时候祭出那张scrapy的经典图了:
从这张图上看,scrapy包含了以下模块:
- scrapy engine,主引擎。在处理数据流时负责管理整个系统,同时各种事件的触发也由其负责。
- spider,即我们的爬虫。主要的爬虫代码都在这部分中,包括发起请求,处理返回的网页等等。
- spider middleware,spider中间件。中间件的一种,主要工作对spider发送的request做一些处理。
- scheduler,调度器。上面说到的url队列就是调度器在管理,一方面接收spider发送的request请求,放入队列中;另一方面会从队首取出request交由downloader去下载网页。
- downloader,下载器。将网页的html源码下载下来供之后的网页分析和信息提取。
- downloader middleware,下载器中间件。中间件的一种,在下在网页之前和之后都会运行,可以用来设置发送请求的header,cookies,代理ip以及处理一些错误返回的情况。
- item pipeline, 管道。一个网页被爬取下来并解析之后,其后续的信息存储之类的工作在pipeline中进行。当然也可以直接在spider中完成这些工作,但在pipeline中完成则显得整个项目结构清晰。
上面列出的里面spider,pipeline需要自己写,两种middleware需要的话可以自己添加自己写的。
光介绍给人感觉比较空洞,那下面就让我们来使用scrapy实现一个简单的爬虫吧。
3. scrapy实现爬虫
scrapy createproject cnblog_project
使用上面的命令创建一个scrapy工程之后,首先我们要写的是spider。
class CnblogSpider(Spider):
name = 'cnblog_spider' # 爬虫名字
allowed_domain = ['cnblogs.com'] # 允许的domain
def __init__(self):
self.start_urls = ['http://www.cnblogs.com/rubinorth']
def start_requests(self):
return [Request(url, callback=self.parse_page) for url in self.start_urls]
# 分析爬取的页面并构造下一个页面的请求
def parse_page(self, response):
logging.info("parse : " + response.url)
sel = Selector(response)
item = CnblogItem()
# 提取页面内容
item['name'] = sel.xpath("//a[@id='Header1_HeaderTitle']/text()").extract()[0]
yield item
# 下一个页面的请求
new_url = get_new_url(response.body) # 根据源码分析出新的链接,需自己实现
yield Request(new_url, callback=self.parse_page)
上面是一个简单的爬虫,start_urls是初始的url集合(上面只有一个),start_requests则根据start_urls构造Request,并交给调度器。parse_page中,response是返回的页面的源码;CnblogItem是scrapy提供的item组件,方便结构化地提取源码中的数据,而yield item则会将这个item交给管道;yield Request(new_url, callback=self.parse_page)则会发送一个新的Request,发起下一轮的爬取。
items.py中只要这么写:
class CnblogItem(scrapy.Item):
name = scrapy.Field()
接着,我们需要写pipelines.py
class CnblogPipeline(object):
def process_item(self, item, spider):
print item['name']
return item
每个pipeline都必须有process_item这个方法。上面我们只是简单地打印出了name。return item是考虑到可能有多个pipeline(return了之后可以让其他pipeline处理)。
最后,只需要修改settings.py即可:
...
ITEM_PIPELINES = {
'yelp_project.pipelines.CnblogPipeline': 304,
}
...
需要在setting中打开自己的pipeline。
好了,一个简单的爬虫就这么写完了。注意我们并没有用到中间件,也不需要写自己的中间件。
最后, 命令行运行:
scrapy crawl cnblog_spider
参考资料
转载请注明出处:http://www.cnblogs.com/rubinorth/
网页爬虫--scrapy入门的更多相关文章
- 网页爬虫--scrapy进阶
本篇将谈一些scrapy的进阶内容,帮助大家能更熟悉这个框架. 1. 站点选取 现在的大网站基本除了pc端都会有移动端,所以需要先确定爬哪个. 比如爬新浪微博,有以下几个选择: www.weibo.c ...
- 爬虫——scrapy入门
scrapy 安装scrapy pip install scrapy windows可能安装失败,需要先安装c++库或twisted,pip install twisted 创建项目 scrapy s ...
- [Python爬虫] scrapy爬虫系列 <一>.安装及入门介绍
前面介绍了很多Selenium基于自动测试的Python爬虫程序,主要利用它的xpath语句,通过分析网页DOM树结构进行爬取内容,同时可以结合Phantomjs模拟浏览器进行鼠标或键盘操作.但是,更 ...
- Scrapy 爬虫框架入门案例详解
欢迎大家关注腾讯云技术社区-博客园官方主页,我们将持续在博客园为大家推荐技术精品文章哦~ 作者:崔庆才 Scrapy入门 本篇会通过介绍一个简单的项目,走一遍Scrapy抓取流程,通过这个过程,可以对 ...
- 0.Python 爬虫之Scrapy入门实践指南(Scrapy基础知识)
目录 0.0.Scrapy基础 0.1.Scrapy 框架图 0.2.Scrapy主要包括了以下组件: 0.3.Scrapy简单示例如下: 0.4.Scrapy运行流程如下: 0.5.还有什么? 0. ...
- 小白学 Python 爬虫(34):爬虫框架 Scrapy 入门基础(二)
人生苦短,我用 Python 前文传送门: 小白学 Python 爬虫(1):开篇 小白学 Python 爬虫(2):前置准备(一)基本类库的安装 小白学 Python 爬虫(3):前置准备(二)Li ...
- 小白学 Python 爬虫(35):爬虫框架 Scrapy 入门基础(三) Selector 选择器
人生苦短,我用 Python 前文传送门: 小白学 Python 爬虫(1):开篇 小白学 Python 爬虫(2):前置准备(一)基本类库的安装 小白学 Python 爬虫(3):前置准备(二)Li ...
- 小白学 Python 爬虫(36):爬虫框架 Scrapy 入门基础(四) Downloader Middleware
人生苦短,我用 Python 前文传送门: 小白学 Python 爬虫(1):开篇 小白学 Python 爬虫(2):前置准备(一)基本类库的安装 小白学 Python 爬虫(3):前置准备(二)Li ...
- 小白学 Python 爬虫(37):爬虫框架 Scrapy 入门基础(五) Spider Middleware
人生苦短,我用 Python 前文传送门: 小白学 Python 爬虫(1):开篇 小白学 Python 爬虫(2):前置准备(一)基本类库的安装 小白学 Python 爬虫(3):前置准备(二)Li ...
随机推荐
- Linux 安装rar解压工具
下载RAR安装包: http://www.rarsoft.com/download.htm 我的是CentOS 64位: wget http://www.rarsoft.com/rar/rarlinu ...
- Java中相等测试
一:equals与==的区别 (1)基本数据类型 byte,short,char,int,long,float,double,boolean 此类数据类型的比较需要使用==,此时比较的是他们的值,若相 ...
- kuangbin_ShortPath D (POJ 3268)
本来在想 单源多点很好解决但是多源单点怎么解 然后我发现只要倒过来就可以了 把输入存下来然后 处理完dis1 重新init一次 倒着再输入一次 处理dis2 输出max(dis1[i] + dis2[ ...
- Linux应用程序的地址布局
转载自:http://blog.csdn.net/embedded_hunter http://www.360doc.com/content/12/0405/00/1671317_200882538. ...
- Lua快速入门
-- 两个横线开始单行的注释 --[[ 加上两个[和]表示 多行的注释. --]] ---------------------------------------------------- -- 1. ...
- MySQL DBA的个人修养
做为一个MySQL DBA,必须具有以下的素质: 一, 身体素质 DBA必须接收和处理各种报警,不论是中午在吃饭或者凌晨三点已经进入深度睡眠.接到报警需要立即进入应急状态,找到电脑,联上网络,快速定位 ...
- python模块结构和布局
用模块来合理的组织你的python代码是简单又自然的方法.下面介绍一种非常合理的布局: #(1)起始行(Unix) #(2)模块文档 #(3)模块导入 #(4)变量定义 #(5)类定义 #(6)函数定 ...
- Share Point 创建 TimerJob
public class SyncMetadataJob:SPJobDefinition { private const string JobName = @"Metadata Sync J ...
- EntityFramework5.0CodeFirst全面学习
Code First 约定 借助 CodeFirst,可通过使用 C# 或Visual Basic .NET 类来描述模型.模型的基本形状可通过约定来检测.约定是规则集,用于在使用 Code Firs ...
- linq 和 , 并 , 差 ,交
假如: A = [--.], B = [-.] A 并 B = 全部 linq : a.union(b) A 交 B = 中间那块 linq: a.Intersect(b) ...