Scrapy
Scrapy
从Python的Urllib、Urlllib2到scrapy,当然,scrapy的性能且效率是最高的,自己之前也看过一些资料,在此学习总结下。
Scrapy介绍
关于scrapy
scrapy是一个健壮的,可以从网络上抓取数据的web框架,只需要一个配置文件就能组合各种组件和配置选项。同时,scrapy是一个基于事件的架构 因此我们可以级联很多操作,包括清理,组织,存储数据到数据库,导出数据等。
假设你现在要抓取一个网站,这个网站的每一页都有一百个条目,Scrapy可以毫不费劲地同时对这个网站发起16个请求,假如每个请求需要一秒钟来完成,就相当于每秒钟爬取16个页面,相当于每秒钟生成了1600个条目,假如要把这些条目同时存储到云上,每一个条目的存储需要3秒钟(假设的),为了处理这16个请求,就需要运行1600 *3 = 4800个并发的写入请求,对于一个传统的多线程程序来说,就需要转换成4800个线程,这会对系统造成极大的压力。而对于Scrapy来说,只要你的硬件过关, 4800个并发请求是没有问题的。
scrapy的优点
Scrapy已经发展了5年有多,已经变得成熟和稳定,除了上面提到的性能优点外,Scrapy还有以下几点优点:
1. Scrapy可以处理不完整的HTML
你可以在Scrapy中使用Beautiful Soup或者lxml,但Scrapy已经提供了selectors(一个在lxml的基础上提供了更高级的接口),可以高效地处理不完整的HTML代码。
2. 活跃的Scrapy社区
Scrapy拥有一个活跃的社区,尤其是在Stack Overflow(https://stackoverflow.com/questions/tagged/Scrapy)上有上千个问题的讨论,更多的社区论坛可以参考这里:http://Scrapy.org/community/
3. 由社区维护的具有良好架构的代码
Scrapy要求你用标准的方式去组织你的代码,所以你在与他人合作时,别人不用苦苦研究你那拥有奇淫技巧的爬虫。
4. 新特性越来越多且质量稳定
通过观察Scrapy的新闻发布页(http://doc.Scrapy.org/en/latest/news.html),就可以看到在增加的新特性和bug修正。
Scrapy基础
安装
我一直是在ubuntu下使用scrapy的 下面就说说ubuntu下scrapy的安装:
$sudo apt-get update
$ sudo apt-get install python-pip python-lxml python-crypto python-cssselect python-openssl python-w3lib python-twisted python-dev
libxml2-dev libxslt1-dev zliblg-dev libffi-dev libssl-dev
$ sudo pip install scrapy
如果想要获得最新版的话,可以使用:
git clone https://github.com/scrapy/scrapy.git
cd scrapy
python setup.py install
升级scrapy
sudo pip install -upgrade scrapy
or
sudo easy_install --upgrade scrapy
当然 也有人是想安装特定的版本的 那么可以使用命令:
sudo pip install scrapy==1.00
or
sudo easy_install scrapy==1.00
爬取过程 - URI^2IM
每个网站都是不一样的,那么使用scrapy爬取时势必会存在差异。但是,当使用scrapy爬取时,使用最多的是UR^2IM流程,分别是:URL,Request,Response,Items,More URLS。
URL
所有的爬虫都是从一个起始的URL(也就是你想要爬取的网站地址)开始,当你想要验证用xpath或者其它解析器来解析这个网页时,可以使用scrapy shell工具来分析。
scrapy shell(scrapy终端)是一个交互式的终端,在未启动spider的情况下尝试及调试爬取代码,主要测试Xpath和CSS表达式等,查看他们的工作方式以及从爬取的网页中提取数据,该终端在开发和调试spider时发挥着巨大的作用。
启动终端:scrapy shell <url>
使用该终端时,可使用一些快捷命令,如下:
shelp | 打印可用对象及快捷命令的帮助列表 |
fetch(request_or_url) | 根据给定的请求(request)或URL获取一个新的response,并更新 相关对象 |
view(response) | 在本机的浏览器打开给定的response |
可用的scrapy对象,scrapy终端会根据下载的页面自动创建一些方便使用的对象,包括:
crawler | 当前的crawler对象 |
spider | 处理URL的spider |
request | 最近获取到的页面的request对象 |
response | 最近获取到的页面的response对象 |
sel | 最近获取到的response构建的Selector对象 |
settings | 当前的scrapy settings |
终端会话样例:爬取"https://baidu.com"的页面。输入:scrapy shell 'http://www.cnblogs.com/ybjourney/' --nolog,会显示相应的各个对象的值,进而在In [1]:中输入:sel.xpath('//div[@class="postTitle"]/a/text()').extract(),验证xpath表达式。
The Request and The Response(请求和响应)
在上面使用scrapy shell就会发现,只要我们输入一个URL,它就可以自动发送一个GET请求并返回结果。request是一个把url封装好的对象,response则是一个把网页返回结果封装好的对象,response.body的值是网页的源代码,response.url是网页的url地址,还有更多相关的属性。
Items
爬虫的目标不只是在爬取到网页的源代码,更重要的是提取网页的相关信息,对于这些内容,在scrapy中被封装为一个Item对象,然后从网页中提取信息来填充这个Item。
从网页中提取信息常用到的方式有很多,比如正则表达式(re),BeautifulSoup,Xpath等,我常用到的就这几种。
scrapy工程
上面我们学习了scrapy的一些基础知识,现在我们动手创建一个scrapy项目,写爬虫~
首先,用命令scrapy startproject yourproject新建一个项目。 cd yourproject
tree
该项目的目录如下:
__init__.py
items.py
pipelines.py
settings.py
spiders
__init__.py
scrapy.cfg
其中,spiders文件中主要是用来编写爬虫(spider)文件,定义了对某个特定网页的类。其它重要的文件包括:items.py,piplines.py,settings.py,分别的作用如下:
items.py:定义需要抓取并需要后期处理的数据,很像字典;
settings.py:文件配置scrapy,从而修改user-agent,设定爬取时间间隔,设置代理,配置各种中间件等,在反爬虫时会用到。
piplines.py:用于存放执行后期数据的功能,将数据的爬取和处理分开。items抓取数据之后送到pipline。
建立project就是不断的对这三个文件进行修改。
编写爬虫
在了解了scrapy项目的目录后,接下来就是编写爬虫了,在这里以爬取我博客园第一页的博客标题、摘要、博客链接为例进行说明。
定义item
爬虫之前,一定是要知道你需要爬取到什么内容,在items.py中定义抓取,在该文件中定义的item并不是一定要在每一个spider中填充,也不是全部同时使用,因为item中的字段可以在不同的spider文件中使用,也可以在一个spider文件的不同地方使用,你只需要在此定义你需要用到的字段,定义之后在任何时候都可以使用。在该例子中的items.py文件如下:
from scrapy import Item,Field class Mych03Item(Item):
Title = Field()
Abstract = Field()
Link = Field()
写爬虫文件
定义了item之后,我们就可以写爬虫文件了,在spider文件夹中建立相应的文件,我们可以开始写爬虫了。
首先,在项目的根目录下根据basic模板创建一个名为basic的spider,后面的web指的是spider的可运行的域名:
scrapy genspider –t basic basic web
在本项目中的命令是:
scrapy genspider -t basic cnblog cnblogs
这样就在spiders文件夹中创建了一个cnblog.py的爬虫文件。
当然可以自己手写一个spider,但是从模板里创建可以省去不少的时间和减少出错机率,查看其他模板的命令:
scrapy genspider -l
使用模板创建的文件如下:
# -*- coding: utf-8 -*-
import scrapy class BasicSpider(scrapy.Spider):
name = "basic"
allowed_domains = ["web"]
start_urls = (
'http://www.web/',
) def parse(self, response):
pass
对该spider文件中的几个变量做出说明:
name:定义的spider名字,该名字在执行这个爬虫文件时会用到,故应保持名字是唯一的;
allowed_domains:允许爬取的域名列表;
start_urls:爬虫的起始地址。
创建好了模板文件,就可以结合之前的内容,编写爬虫文件了,编写cnblog.py文件如下:
# coding:utf-8
import scrapy
from mych03.items import Mych03Item
from scrapy.selector import Selector
from scrapy.utils.response import get_base_url class CnblogSpider(scrapy.Spider):
name = "cnblog"
allowed_domains = ["cnblogs"]
start_urls = (
'http://www.cnblogs.com/ybjourney/default.html?page=1',
) def parse(self, response):
items = []
sel = Selector(response)
base_url = get_base_url(response)
postTitle = sel.css('div.postTitle')
postAbstract = sel.css('div.c_b_p_desc')
for index in range(len(postTitle)):
item = Mych03Item()
item['Title'] = postTitle[index].css("a").xpath(u'text()').extract()[0]
item['Link'] = postTitle[index].css('a').xpath('@href').extract()[0]
item['Abstract'] = postAbstract.xpath('text()').extract()[0]
return items
运行:scrapy crawl spidername
保存文件:scrapy crawl spider -o filename.json/csv
保存之后就可以在项目的根目录下找到你所保存的.csv或者.json文件了。
Spider的运行原理
我们写了爬虫文件,现在,结合scrapy项目文件目录,对Spider的运行原理进行说明:
首先要将指定的初始URL封装成Request对象,并且指定在网页返回该请求的内容后应该用哪个函数来处理网页的内容。一般都会调用start_request()函数,对start_urls中的URL分别生成一个Request对象,并使用callback变量指定相应的parse()函数作为回调函数。
在回调函数中,处理response变量,返回item对象,一个字典,或者Request对象(可以指定callback,指定一个回调函数,也就是在处理完这个Request之后生成的response会传送到回调函数中处理)。
在回调函数中,使用Xpath等类提取网页中需要的内容,存入item。
从spider中返回的item写入文件或者数据库中。
如果你看到这里,那么恭喜你,已经会写一个简单的爬虫了。
Scrapy的更多相关文章
- Scrapy框架爬虫初探——中关村在线手机参数数据爬取
关于Scrapy如何安装部署的文章已经相当多了,但是网上实战的例子还不是很多,近来正好在学习该爬虫框架,就简单写了个Spider Demo来实践.作为硬件数码控,我选择了经常光顾的中关村在线的手机页面 ...
- scrapy爬虫docker部署
spider_docker 接我上篇博客,为爬虫引用创建container,包括的模块:scrapy, mongo, celery, rabbitmq,连接https://github.com/Liu ...
- scrapy 知乎用户信息爬虫
zhihu_spider 此项目的功能是爬取知乎用户信息以及人际拓扑关系,爬虫框架使用scrapy,数据存储使用mongo,下载这些数据感觉也没什么用,就当为大家学习scrapy提供一个例子吧.代码地 ...
- ubuntu 下安装scrapy
1.把Scrapy签名的GPG密钥添加到APT的钥匙环中: sudo apt-key adv --keyserver hkp://keyserver.ubuntu.com:80 --recv 6272 ...
- 网络爬虫:使用Scrapy框架编写一个抓取书籍信息的爬虫服务
上周学习了BeautifulSoup的基础知识并用它完成了一个网络爬虫( 使用Beautiful Soup编写一个爬虫 系列随笔汇总 ), BeautifulSoup是一个非常流行的Python网 ...
- Scrapy:为spider指定pipeline
当一个Scrapy项目中有多个spider去爬取多个网站时,往往需要多个pipeline,这时就需要为每个spider指定其对应的pipeline. [通过程序来运行spider],可以通过修改配置s ...
- scrapy cookies:将cookies保存到文件以及从文件加载cookies
我在使用scrapy模拟登录新浪微博时,想将登录成功后的cookies保存到本地,下次加载它实现直接登录,省去中间一系列的请求和POST等.关于如何从本次请求中获取并在下次请求中附带上cookies的 ...
- Scrapy开发指南
一.Scrapy简介 Scrapy是一个为了爬取网站数据,提取结构性数据而编写的应用框架. 可以应用在包括数据挖掘,信息处理或存储历史数据等一系列的程序中. Scrapy基于事件驱动网络框架 Twis ...
- 利用scrapy和MongoDB来开发一个爬虫
今天我们利用scrapy框架来抓取Stack Overflow里面最新的问题(),并且将这些问题保存到MongoDb当中,直接提供给客户进行查询. 安装 在进行今天的任务之前我们需要安装二个框架,分别 ...
- python3 安装scrapy
twisted(网络异步框架) wget https://pypi.python.org/packages/dc/c0/a0114a6d7fa211c0904b0de931e8cafb5210ad82 ...
随机推荐
- Android 身份证号码查询、手机号码查询、天气查询
1.基本信息 身份证号码查询:http://apistore.baidu.com/apiworks/servicedetail/113.html 手机号码:http://apistore.baidu. ...
- 安卓开发_慕课网_ViewPager实现Tab(App主界面)
学习内容来自“慕课网” 网站上一共有4种方法来实现APP主界面的TAB方法 这里学习第一种 ViewPager实现Tab 布局文件有7个, 主界面acitivity.layout <Linear ...
- IOS客户端Coding项目记录(五)
1:统一修改导航栏的样式,在 AppDelegate.m中 - (BOOL)application:(UIApplication *)application didFinishLaunchingWit ...
- 【读书笔记】iOS-NSPredicate
一,Cocoa提供了一个名为NSPredicate的类,它用于指定过滤器的条件.可以创建NSPredicate对象,通过该对象准确地描述所需的条件,对每个对象通过谓词进行筛选,判断它们是否与条件相匹配 ...
- 多线程之NSThread和NSObject
#pragma mark - NSThread实现多线程 /* // 获取当前线程 NSLog(@"currentThread = %@", [NSThread currentTh ...
- JAVA基础学习day17--集合工具类-Collections
一.Collection简述 1.1.Collection与Collections的区别 Collections是集合的静态工具类 Collection:是集合的顶级接口 二.Sort 2.1.sor ...
- iOS开发笔记7:Text、UI交互细节、两个动画效果等
Text主要总结UILabel.UITextField.UITextView.UIMenuController以及UIWebView/WKWebView相关的一些问题. UI细节主要总结界面交互开发中 ...
- Effective Java 70 Document thread safety
Principle The presence of the synchronized modifier in a method declaration is an implementation det ...
- LightSpeed的批量更新和批量删除
1.Update对于批量操作 无论是Update还是Remove 都是使用LightSpeed的Query对象来完成. 注:Student是要进行Update的表(实体),StuName是表Stud ...
- C#XmlHelper操作Xml文档的帮助类
using System.Xml; using System.Data; namespace DotNet.Utilities { /// <summary> /// Xml的操作公共类 ...