scrapy实现全站抓取数据
1. scrapy.CrawlSpider
scrapy框架提供了多种类型的spider,大致分为两类,一类为基本spider(scrapy.Spider),另一类为通用spider(scrapy.spiders.CrawlSpider、scrapy.spiders.XMLFeedSpider、scrapy.spiders.CSVFeedSpider、scrapy.spiders.SitemapSpider),并且值得注意的是,通用spider类型,均继承scrapy.Spider,那么我们在使用通用spider来抓取网页的时候,其解析方法名不能是parse(那样就重写了其父类Spider的parse方法,造成冲突)。
为什么可以使用CrawlSpider进行全站抓取呢? 那么可以想像一下, 我们如果不使用它如何实现全站抓取, 首先我们需要解析一个网站的首页, 解析出其所有的资源链接(ajax方式或绑定dom事件实现跳转忽略),请求该页面所有的资源链接, 再在资源链接下递归地查找子页的资源链接,最后在我们需要的资源详情页结构化数据并持久化在文件中。这里只是简单的介绍一下全站抓取的大致思路,事实上,其细节的实现,流程的控制是很复杂的,所以scrapy封装了一个CrawlSpider,使得数据的爬取变得简单高效,因为它通过定义一组规则为跟踪链接提供了便利的机制。它可能不是最适合您的特定网站或项目,但它在几种情况下足够通用,因此您可以从它开始并根据需要覆盖它以获得更多自定义功能。
2. 重要属性
A . rules:这是一个(或多个)Rule对象的列表。每个都Rule 定义了爬网站点的特定行为。规则对象如下所述。如果多个规则匹配相同的链接,则将根据它们在此属性中定义的顺序使用第一个规则。
补充:class scrapy.spiders.Rule(link_extractor,callback = None,cb_kwargs = None,follow = None,process_links = None,process_request = None )
1.link_extractor是一个Link Extractor对象,它定义如何从每个已爬网页面中提取链接,可以是正则表达式,用于在跟进的时候筛选url(*重要*)。
2.callback是一个可调用的或一个字符串(在这种情况下,将使用来自具有该名称的spider对象的方法)为使用指定的link_extractor提取的每个链接调用。此回调接收响应作为其第一个参数,并且必须返回包含Item和/或 Request对象(或其任何子类)的列表(*重要*)。
3.cb_kwargs 是一个包含要传递给回调函数的关键字参数的dict。
4.follow是一个布尔值,指定是否应该从使用此规则提取的每个响应中跟踪链接。如果callback是follow默认值True,则默认为False(*重要*)。
5.process_links是一个可调用的,或一个字符串(在这种情况下,将使用来自具有该名称的spider对象的方法),将使用指定的每个响应从每个响应中提取的每个链接列表调用该方法link_extractor。这主要用于过滤目的。
6.process_request 是一个可调用的,或一个字符串(在这种情况下,将使用来自具有该名称的spider对象的方法),该方法将在此规则提取的每个请求中调用,并且必须返回请求或None(以过滤掉请求)
B . ...................(Spider的allowed_domains、start_urls等)
3. 实战需求
"""
爬取微信小程序社区所有教程(http://www.wxapp-union.com/portal.php?mod=list&catid=2),并以json格式存储在文件中
"""
4. 实现
补充:新建CrawlSpider模板的爬虫的命令 scrapy genspider -t crawl wxappcrawl wxapp-union.com
settings.py
# Obey robots.txt rules
ROBOTSTXT_OBEY = False # Override the default request headers:
DEFAULT_REQUEST_HEADERS = {
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
'Accept-Language': 'en',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/72.0.3626.119 Safari/537.36', } DOWNLOAD_DELAY = 3 # Configure item pipelines
# See https://doc.scrapy.org/en/latest/topics/item-pipeline.html
ITEM_PIPELINES = {
'wxapp.pipelines.WxappPipeline': 300,
}
wxappcrawl .py
# -*- coding: utf-8 -*-
import scrapy
from scrapy.linkextractors import LinkExtractor
from scrapy.spiders import CrawlSpider, Rule
from .. import items class WxappcrawlSpider(CrawlSpider):
name = 'wxappcrawl'
allowed_domains = ['wxapp-union.com']
start_urls = ['http://www.wxapp-union.com/portal.php?mod=list&catid=2&page=1'] '''
allow设置之后, 会在执行其父类(scrapy.Spider)的parse方法的时候, 提取response中符合这一正则的所有
url, 并添加到调度器下的请求队列(无重复)中
'''
rules = (
# 爬取每一页
Rule(LinkExtractor(allow=r'.+?mod=list&catid=2&page=\d'), follow=True),
# 爬取具体的文章页
Rule(LinkExtractor(allow=r'.+/article-\d+-\d+\.html'), callback='parse_article', follow=False),
) def parse_article(self, response):
'''
解析文章页,并返回实体
'''
article_title = response.xpath("//h1[@class='ph']/text()").get().strip()
article_author = response.xpath("//p[@class='authors']/a/text()").get().strip()
article_ctime = response.xpath("//p[@class='authors']/span[@class='time']/text()").get()
article_content_list = response.xpath("//td[@id='article_content']/*/text()").getall()
article_content = ''.join(article_content_list) yield items.WxappItem(
title = article_title,
author = article_author,
ctime = article_ctime,
content = article_content
)
items.py
# -*- coding: utf-8 -*- # Define here the models for your scraped items
#
# See documentation in:
# https://doc.scrapy.org/en/latest/topics/items.html import scrapy class WxappItem(scrapy.Item):
# define the fields for your item here like:
# name = scrapy.Field() title = scrapy.Field()
author = scrapy.Field()
ctime = scrapy.Field()
content = scrapy.Field()
pipelines.py
# -*- coding: utf-8 -*- # Define your item pipelines here
#
# Don't forget to add your pipeline to the ITEM_PIPELINES setting
# See: https://doc.scrapy.org/en/latest/topics/item-pipeline.html from scrapy.exporters import JsonLinesItemExporter class WxappPipeline(object): def __init__(self):
self.file = open('./wxapp.json', 'wb')
self.exporter = JsonLinesItemExporter(file=self.file, ensure_ascii=False, encoding='utf-8') def open_spider(self, spider):
pass def process_item(self, item, spider):
self.exporter.export_item(item)
return item def close_spider(self, spider):
self.file.close()
run.py (在项目根目录下(与scrapy.cfg同级)新建启动爬虫的py文件)
from scrapy import cmdline
cmdline.execute("scrapy crawl wxappcrawl".split())
# cmdline.execute(['scrapy', 'crawl', 'wxappcrawl'])

哈哈·,收工!
scrapy实现全站抓取数据的更多相关文章
- 分布式爬虫:使用Scrapy抓取数据
分布式爬虫:使用Scrapy抓取数据 Scrapy是Python开发的一个快速,高层次的屏幕抓取和web抓取框架,用于抓取web站点并从页面中提取结构化的数据.Scrapy用途广泛,可以用于数据挖掘. ...
- [转]使用scrapy进行大规模抓取
原文:http://www.yakergong.net/blog/archives/500 使用scrapy有大概半年了,算是有些经验吧,在这里跟大家讨论一下使用scrapy作为爬虫进行大规模抓取可能 ...
- nodejs--实现跨域抓取数据
最近公司安排给我一个任务,抓取页面数据:http://survey.finance.sina.com.cn/static/20205/20131120.html?pid=20205&dpc=1 ...
- java抓取网页数据,登录之后抓取数据。
最近做了一个从网络上抓取数据的一个小程序.主要关于信贷方面,收集的一些黑名单网站,从该网站上抓取到自己系统中. 也找了一些资料,觉得没有一个很好的,全面的例子.因此在这里做个笔记提醒自己. 首先需要一 ...
- C# WebBrowser控件 模拟登录 抓取数据
参考博客:C#中的WebBrowser控件的使用 参考博客:C#中利用WebBrowser控件,获得HTML源码 一.问题点: 1.模拟登录后,如果带有嵌套的iframe嵌套,不好读取iframe内容 ...
- PHP的cURL库:抓取网页,POST数据及其他,HTTP认证 抓取数据
From : http://developer.51cto.com/art/200904/121739.htm 下面是一个小例程: ﹤?php// 初始化一个 cURL 对象$curl = curl_ ...
- php中封装的curl函数(抓取数据)
介绍一个封闭好的函数,封闭了curl函数的常用步骤,方便抓取数据. 代码如下: <?php /** * 封闭好的 curl函数 * 用途:抓取数据 * edit by www.jbxue.com ...
- php中CURL技术模拟登陆抓取数据实战,抓取某校教务处学生成绩。
这两天有基友要php中curl抓取教务处成绩的源码,用于微信公众平台的开发.下面笔者只好忍痛割爱了.php中CURL技术模拟登陆抓取数据实战,抓取沈阳工学院教务处学生成绩. 首先,教务处登录需要验证码 ...
- 【转】蓝牙4.0BLE cc2540 usb-dongle的 SmartRF Packet Sniffer 抓取数据方法--不错
原文网址:http://blog.csdn.net/mzy202/article/details/32408223 蓝牙4.0BLE cc2540 usb-dongle的 SmartRF Packet ...
随机推荐
- Rabbitmq笔记二
消息何去何从 mandatory 和 immediate 是 channel . basicPublish 方法中的两个参数,它们都有 当消息传递过程中不可达目的地时将消息返回给生产者的功能. 当 m ...
- Windows 程序设计 笔记
知识点 双字节字符集和Unicode字符集有何区别?采用双字节字符集有何问题 双字节字符集(DBCS)编码是0-255,DBCS含有1字节代码与2字节代码,而Unicode是统一的16位系统,这样就允 ...
- [POI2007]对称轴osi
Description FGD小朋友--一个闻名遐迩的年轻数学家--有一个小MM,yours.FGD小朋友非常喜欢他的MM,所以他很乐意帮助他的MM做数学作业.但是,就像所有科学的容器一样,FGD的大 ...
- 51nod 1116 K进制下的大数
你万万想不到,Long Long 就能存下的数据 #include <iostream> #include <cstdio> #include <cstdlib> ...
- 1.1.1最短路(Floyd、Dijstra、BellmanFord)
转载自hr_whisper大佬的博客 [ 一.Dijkstra 比较详细的迪杰斯特拉算法讲解传送门 Dijkstra单源最短路算法,即计算从起点出发到每个点的最短路.所以Dijkstra常常作为其他算 ...
- 暴力/进制转换 Codeforces Round #308 (Div. 2) C. Vanya and Scales
题目传送门 /* 题意:问是否能用质量为w^0,w^1,...,w^100的砝码各1个称出重量m,砝码放左边或在右边 暴力/进制转换:假设可以称出,用w进制表示,每一位是0,1,w-1.w-1表示砝码 ...
- 总结用CoreText绘制文本时遇到的问题以及解决办法
关于CoreText不做解释.用的人自然知道这个是干什么的. 功能非常强大,可以绘制文本,图片等. 这次用的Xcode7.0的版本.所以之前很多方法,现在不能用.也不是不能用,就是有黄色警告很不爽. ...
- 转 ORA-12638: 身份证明检索失败
ORA-12638: 身份证明检索失败 的解决办法 2008年06月25日 星期三 11:42 the NTS option makes the Oracle client attempt to us ...
- ASP.NET Core MVC使用MessagePack配合前端fetch交换数据
1.安装Nuget包 - WebApiContrib.Core.Formatter.MessagePack https://www.nuget.org/packages/WebApiContrib.C ...
- SpringMVC -- 必知必会
SpringMVC基于模型--视图--控制器(Model-View-Controller,MVC)模式实现,属于SpringFrameWork的后续产品,已经融合在SpringWebFlow里面.它通 ...