用Scrapy写一个爬虫
昨天用python谢了一个简单爬虫,抓取页面图片;
但实际用到的爬虫需要处理很多复杂的环境,也需要更加的智能,重复发明轮子的事情不能干,
再说python向来以爬虫作为其擅长的一个领域,想必有许多成熟的第三方框架,百度后选用了
Scrapy作为平台构建复杂爬虫。
Scarpy的下载安装不必细说,话说当前只支持python2.x版本,很郁闷,下载安装了python2.7。
安装完后,按照《Scrapy Tutorial》和Scrapy at a glance两篇帖子作为学习范本。
概念及步骤简要摘录总结如下:
Scrapy是一个为了爬取网站数据,提取结构性数据而编写的应用框架。 可以应用在包括数据挖掘,信息处理或存储历史数据等一系列的程序中。
其最初是为了页面抓取 (更确切来说, 网络抓取 )所设计的, 也可以应用在获取API所返回的数据(例如 Amazon Associates Web Services ) 或者通用的网络爬虫。Scrapy用途广泛,可以用于数据挖掘、监测和自动化测试。
Scrapy 使用了 Twisted异步网络库来处理网络通讯。整体架构大致如下:
Scrapy Architecture
Scrapy主要包括了以下组件:
引擎
:用来处理整个系统的数据流处理,触发事务。调度器
:用来接受引擎发过来的请求,压入队列中,并在引擎再次请求的时候返回。下载器
:用于下载网页内容,并将网页内容返回给蜘蛛。蜘蛛
:蜘蛛是主要干活的,用它来制订特定域名或网页的解析规则。项目管道
:负责处理有蜘蛛从网页中抽取的项目,他的主要任务是清晰、验证和存储数据。当页面被蜘蛛解析后,将被发送到项目管道,并经过几个特定的次序处理数据。下载器中间件
:位于Scrapy引擎和下载器之间的钩子框架,主要是处理Scrapy引擎与下载器之间的请求及响应。蜘蛛中间件
:介于Scrapy引擎和蜘蛛之间的钩子框架,主要工作是处理蜘蛛的响应输入和请求输出。调度中间件
:介于Scrapy引擎和调度之间的中间件,从Scrapy引擎发送到调度的请求和响应。
使用Scrapy可以很方便的完成网上数据的采集工作,它为我们完成了大量的工作,而不需要自己费大力气去开发。
主要步骤:
1. 创建一个Scrapy项目
2. 定义提取的Item
3. 编写爬取网站的 spider 并提取 Item
4. 编写 Item Pipeline 来存储提取到的Item(即数据)
1.scrapy startproject bbsdmoz
2.编辑 bbsDmoz 目录中的 items.py
文件,根据需要从bbs网站获取到的数据对item进行建模;
1 # -*- coding: utf-8 -*-
2 # Define here the models for your scraped items
3 # See documentation in:
4 # http://doc.scrapy.org/en/latest/topics/items.html
5 from scrapy.item import Item, Field
6 class BbsDmozItem(Item):
7 # define the fields for your item here like:
8 # name = scrapy.Field()
9 url = Field()
forum = Field()
poster = Field()
12 content = Field()
3.创建一个Spider,保存在 bbsDmoz/spiders,您必须继承 scrapy.Spider 类。
从网页中提取数据有很多方法。Scrapy使用了一种基于 XPath 和 CSS 表达式机制: Scrapy Selectors 。
这里给出XPath表达式的例子及对应的含义:
/html/head/title
: 选择HTML文档中<head>
标签内的<title>
元素/html/head/title/text()
: 选择上面提到的<title>
元素的文字//td
: 选择所有的<td>
元素//div[@class="mine"]
: 选择所有具有class="mine"
属性的div
元素
Selector有四个基本的方法(点击相应的方法可以看到详细的API文档):
xpath()
: 传入xpath表达式,返回该表达式所对应的所有节点的selector list
列表 。css()
: 传入CSS表达式,返回该表达式所对应的所有节点的selector list
列表.extract()
: 序列化该节点为unicode字符串并返回list
。re()
: 根据传入的正则表达式对数据进行提取,返回unicode字符串list列表。
4.编写spider代码;
Spider代码
以下为我们的第一个Spider代码
,保存在 bbsDmoz/spiders
目录下的 forumSpider.py
文件中:
1 #-*- coding: utf-8 -*-
2 '''
3 bbsSpider, Created on Oct, 2014
4 #version: 1.0
5 #author: chenqx @http://chenqx.github.com
6 See more: http://doc.scrapy.org/en/latest/index.html
7 '''
8 from scrapy.selector import Selector
9 from scrapy.http import Request
from scrapy.contrib.spiders import CrawlSpider
from scrapy.contrib.loader import ItemLoader
from scrapy.contrib.linkextractors.sgml import SgmlLinkExtractor
from bbs.items import BbsItem
class 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()
5.编写 ItemPipeline
当Item在Spider中被收集之后,它将会被传递到Item Pipeline,一些组件会按照一定的顺序执行对Item的处理。
每个item pipeline组件(有时称之为“Item Pipeline”)是实现了简单方法的Python类。他们接收到Item并通过它执行一些行为,同时也决定此Item是否继续通过pipeline,或是被丢弃而不再进行处理。
以下是item pipeline
的一些典型应用:
- 清理HTML数据
- 验证爬取的数据(检查item包含某些字段)
- 查重(并丢弃)
- 将爬取结果保存,如保存到数据库、XML、JSON等文件中
这个例子将spider从bbs收集来的item写入data.xml文件。
1 # -*- coding: utf-8 -*-
2 # Define your item pipelines here
3 # Don't forget to add your pipeline to the ITEM_PIPELINES setting
4 # See: http://doc.scrapy.org/en/latest/topics/item-pipeline.html
5 from scrapy import signals
6 from scrapy import log
7 from bbsDmoz.items import BbsDmozItem
8 from twisted.enterprise import adbapi
9 from scrapy.contrib.exporter import XmlItemExporter
from dataProcess import dataProcess
class 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
6.编辑setting.py,关联spider与ItemPipeline
1 # -*- coding: utf-8 -*-
2 # Scrapy settings for bbs project
3 # For simplicity, this file contains only the most important settings by
4 # default. All the other settings are documented here:
5 # http://doc.scrapy.org/en/latest/topics/settings.html
6 BOT_NAME = 'bbsDomz'
7 CONCURRENT_REQUESTS = 200
8 LOG_LEVEL = 'INFO'
9 COOKIES_ENABLED = True
RETRY_ENABLED = True
SPIDER_MODULES = ['bbsDomz.spiders']
NEWSPIDER_MODULE = 'bbsDomz.spiders'
# JOBDIR = 'jobdir'
ITEM_PIPELINES = {
'bbsDomz.pipelines.XmlWritePipeline': 1000,
}
7.大功告成,运行一下测试一下吧。
进入项目的根目录bbsDomz/
下,执行下列命令启动spider:
scrapy crawl bbsSpider
可以看到命令窗口飞速删除bbs的内容,当然是u1234类似的编码,data.xml文件在不断变大,用sublime可以看到其中的汉字内容。
ctrl+c可以中断运行,很奇怪,一中断后,xml文件读不出来了。
用Scrapy写一个爬虫的更多相关文章
- 使用Scrapy创建一个爬虫
使用Scrapy创建一个爬虫 创建项目 您可以使用下面的命令来创建 Scrapy 项目: scrapy startproject 项目名称 例:scrapy startproject scrapy_p ...
- 用Node+wechaty写一个爬虫脚本每天定时给女(男)朋友发微信暖心话
wechatBot 微信每日说,每日自动发送微信消息给你心爱的人 项目介绍 灵感来源 在掘金看到了一篇<用Node + EJS写一个爬虫脚本每天定时女朋友发一封暖心邮件>后, 在评论区偶然 ...
- Python:Scrapy(二) 实例分析与总结、写一个爬虫的一般步骤
学习自:Scrapy爬虫框架教程(二)-- 爬取豆瓣电影TOP250 - 知乎 Python Scrapy 爬虫框架实例(一) - Blue·Sky - 博客园 1.声明Item 爬虫爬取的目标是从非 ...
- 用python写一个爬虫——爬取性感小姐姐
忍着鼻血写代码 今天写一个简单的网上爬虫,爬取一个叫妹子图的网站里面所有妹子的图片. 然后试着先爬取了三页,大概有七百多张图片吧!各个诱人的很,有兴趣的同学可以一起来爬一下,大佬级程序员勿喷,简单爬虫 ...
- 使用scrapy写好爬虫进行工作的时候,遇到错误及解决方法
如图中所标出的,提示参数的问题 解决办法: spider目录下的 爬虫文件内容做些更改: 出现报错的文件内容: from scrapy.spiderfrom scrapy.selector impor ...
- 自己写一个爬虫 copider
copider 模仿scrapy的一些写法,当然我这个是单进程的,不是异步的 1.目录 copider/copider.py #coding=utf-8 ''' Created on 2015年10月 ...
- 用 Python + itchat 写一个爬虫脚本每天定时给女朋友发微信暖心话
https://github.com/sfyc23/EverydayWechat.git
- python scrapy 入门,10分钟完成一个爬虫
在TensorFlow热起来之前,很多人学习python的原因是因为想写爬虫.的确,有着丰富第三方库的python很适合干这种工作. Scrapy是一个易学易用的爬虫框架,尽管因为互联网多变的复杂性仍 ...
- scrapy 的一个例子
1.目标: scrapy 是一个爬虫构架,现用一个简单的例子来讲解,scrapy 的使用步骤 2.创建一个scrapy的项目: 创建一个叫firstSpider的项目,命令如下: scrapy sta ...
随机推荐
- less.css基础学习,陆续更新中
//基础//概念:动态样式语言,有很多语言的特性:变量,函数,运算等 //变量:通过一个简单的@+字母,数字下划线等,但不能以数字开头,不能关键字,保留字等//注意less.css是全局变量,除在函数 ...
- ubuntu 创建eclipse 快捷方式
Ubuntu 上链接快捷方式,将想面内容复制并修改,命名为:eclipse.desktop #!/usr/bin/env xdg-open [Desktop Entry] Name=Eclipse C ...
- 学习手机游戏开发的两个方向 Cocos2d-x 和 Unity 3D/2D,哪个前景更好?
如题! 首先说一说学习手机游戏(移动游戏)这件事. 眼下移动互联网行业的在以井喷状态发展.全球几十亿人都持有智能终端设备(ios android),造就了非常多移动互联网创业机会: 一.移动社交 微信 ...
- Yii PHP Framework有用新手教程
说明:由于近期工作工作关系,须要开发一个在Linux下执行的Web Application,须要对如今比較流行的一些PHP框架做一个了解和评估,以下的这篇文章是笔者近期学习一个比較新的PHP Fram ...
- Bitmap的一些操作
1.截取 Bitmap 的部分区域 mBitmap = Bitmap.createBitmap(bmp, 100, 100, 120, 120); 这句代码从 bmp 的 (100,100) 处截取 ...
- ftp nfs samba比较
首先从字面意思上区分一下:1. FTP(文件传输协议)2. NFS(网络文件系统)3. samba 即smb(服务信息块)协议其中FTP 是TCP/IP协议栈所提供的一种子协议,该子协议具体可以实现在 ...
- SqlServer2000下实现行列转换
SqlServer2000下实现行列转换 2011-04-06 22:07:07| 分类: SQL Server | 标签:sqlserver 2000 行列转换 sql |举报|字号 订 ...
- iOS中你必须了解的多线程
多线程概念详解 什么是进程? 简单的说进程就是我们电脑上运行的一个个应用程序,每一个程序就是一个进程,并且每个进程之间是独立的,每个进程运行在其专用受保护的内存空间内(window系统可以通过任务管理 ...
- C#--接口的实现
接口: 不允许使用访问修饰符,所有接口成员都是公共的. 接口成员不能包含代码体. 接口不能定义字段成员. 接口成员不能使用关键字static,vritual,abstract,sealed来定义. 类 ...
- php多文本框提交
<form action="" method="post"><input type=text name=name[]><input ...