引言

本篇介绍Crawlspider,相比于Spider,Crawlspider更适用于批量爬取网页

Crawlspider

  • Crawlspider适用于对网站爬取批量网页,相对比Spider类,CrawSpider主要使用规则(rules)来提取链接,通过定义一组规则为跟踪链接提供了遍历的机制。
  • Crawlspider 的强大体现在自动爬取页面所有符合规则的链接并深入下去!

全站数据爬取

编码流程

  1. 新建一个工程

  2. cd 工程

  3. 创建爬虫文件: scrapy genspider -t crawl spiderName 地址 (crawlspider 继承 scrapy.Spider)

    • 链接提取器 LinkExtractor

      • 可以根据指定的规则对指定的链接进行提取

        • 提取的规则就是构造方法中的 allow(‘正则表达式’) 参数决定
    • 规则解析器 Rule
      • 可以将链接提取器提到的链接进行请求,可以根据指定的规则(callback)对请求到的数据进行解析

    Rule(link, callback='parse_item', follow=True)

    • follow = True 表示每一个页码都当作起始url 然后进行链接提取,如果为 false 只能提取到第一页的几个页码。

    • follow = True; 将链接提取器 继续作用到 连接提取器提取到的链接 所对应的 页码源码中。

scrapy中发送请求的几种方式:

  • start_url
  • self.Request()
  • 链接提取器

例子

使用CrawlSpider模板批量爬取(阳光热线问政平台的投诉帖子)的主题、状态和详细内容

地址为:http://wz.sun0769.com/html/top/reply.shtml

① 定义spider

scrapy genspider -t crawl sun 创建一个spider

在该spider文件中:

  • 定义 LinkExtractor 获取每个页面中的页码的url地址。
  • 定义 Rule ,放入 LinkExtractor 以及 callback ,对于 follow 值得话,如果为True得话,将继续作用到 LinkExtractor 提取到的链接 所对应的 页码源码中。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
# sun.py
# -*- coding: utf-8 -*-
import scrapy
from scrapy.linkextractors import LinkExtractor
from scrapy.spiders import CrawlSpider, Rule
from sunPro.items import Item1, Item2 class SunSpider(CrawlSpider):
name = 'sun'
# allowed_domains = ['www.xxx.com']
start_urls = ['http://wz.sun0769.com/html/top/reply.shtml']
# 链接提取器(如:获得每一个页码)
link = LinkExtractor(allow=r'page=\d+') # 空的话取所有url
link_1 = LinkExtractor(allow=r'page=$') # 拿到第一页数据
link_detail = LinkExtractor(allow=r'question/\d+/\d+\.shtml') # 拿到第一页数据 . 需要转义 rules = (
# 实例化一个Rule(规则解析器)对象
Rule(link, callback='parse_item', follow=True),
Rule(link_1, callback='parse_item'),
Rule(link_detail, callback='parse_detail'),
# follow = True; 将链接提取器 继续作用到 连接提取器提取到的链接 所对应的 页码源码中
) # 数据解析: 用来解析连接提取器提取到的链接所对应的页码
def parse_item(self, response):
# tr_list = response.xpath('/html/body/div[8]/table[2]/tbody/tr') # xpath中不能含有tbody
tr_list = response.xpath('/html/body/div[8]/table[2]//tr') for tr in tr_list:
title = tr.xpath('./td[3]/a[1]/text()').extract_first()
status = tr.xpath('./td[4]/span/text()').extract_first()
num = tr.xpath('./td[1]/text()').extract_first()
# print(num, title,status)
item = Item2()
item['title'] = title
item['status'] = status
item['num'] = num
yield item
# print(response) # 解析详情页中的新闻内容
def parse_detail(self, response):
content = response.xpath('/html/body/div[9]/table[2]//tr[1]/td//text()').extract()
if content:
content = ''.join(content)
num = response.xpath('/html/body/div[9]/table[1]//tr/td[2]/span[2]').extract_first().split(':')[-1].replace(
r'</span>', '')
# print(num, content)
item = Item1()
item['content'] = content
item['num'] = num
yield item

② 定义Item类

  1. 两个Rule是为了拿到所有页码的url,它对应着 Item2
  2. 另一个Rule是为了拿到所有详情页的url,它对应着 Item1
1
2
3
4
5
6
7
8
9
10
11
12
13
# items.py
import scrapy class Item1(scrapy.Item):
# define the fields for your item here like:
content = scrapy.Field()
num = scrapy.Field() class Item2(scrapy.Item):
# define the fields for your item here like:
title = scrapy.Field()
status = scrapy.Field()
num = scrapy.Field()

③ 定义pipeline

定义pipeline做持久化存储!

  1. open_spider 中开起连接
  2. close_spider 中关闭连接
  3. process_item 中执行数据库得插入操作。

遇到的问题:

  • 第一个问题:主题和状态与详细内容如何对应起来呢?

    • 通过对页面进行分析发现,使用在这两个页面中都有编号,所以增加一个新的字段变化,来连接这两块。
  • 两个数据解析函数不同于使用scrapy.Request进行手动传参,然后通过回调来进行连接。而现在只能定义两个 Item ,在管道中如何判断item类型:

    • item.__class__.__name__ 表示类名
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
# pipeline.py
import pymysql class SunproPipeline(object):
conn = None
cursor = None def open_spider(self, spider):
self.conn = pymysql.Connection(host='127.0.0.1', user='root', password="2296",
database='spider', charset='utf8') def process_item(self, item, spider):
self.cursor = self.conn.cursor()
if item.__class__.__name__ == 'Item1':
content = item['content']
num = item['num']
query_sql = 'select * from sun where num = %s'
self.cursor.execute(query_sql, (num,))
ret = self.cursor.fetchall()
if ret:
insert_sql = f'update sun set content = %s where num=%s'
try:
self.cursor.execute(insert_sql, (content, num))
self.conn.commit()
except Exception as e:
print(e)
self.conn.rollback()
else:
insert_sql = f'insert into sun(num,content) values (%s, %s)'
try:
self.cursor.execute(insert_sql, (num, content))
self.conn.commit()
except Exception as e:
print(e)
self.conn.rollback()
else:
title = item['title']
status = item['status']
num = item['num']
query_sql = f'select * from sun where num = %s'
self.cursor.execute(query_sql, (num,))
ret = self.cursor.fetchall()
if ret:
insert_sql = f'update sun set title = %s,status = %s where num=%s'
try:
self.cursor.execute(insert_sql, (title, status, num))
self.conn.commit()
except Exception as e:
print(e)
self.conn.rollback()
else:
insert_sql = f'insert into sun(num,title,status) values (%s, %s,%s)'
try:
self.cursor.execute(insert_sql, (num, title, status))
self.conn.commit()
except Exception as e:
print(e)
self.conn.rollback() return item def close_spider(self, spider):
self.cursor.close()
self.conn.close()

Scrapy框架——使用CrawlSpider爬取数据的更多相关文章

  1. 基于scrapy框架输入关键字爬取有关贴吧帖子

    基于scrapy框架输入关键字爬取有关贴吧帖子 站点分析 首先进入一个贴吧,要想达到输入关键词爬取爬取指定贴吧,必然需要利用搜索引擎 点进看到有四种搜索方式,分别试一次,观察url变化 我们得知: 搜 ...

  2. scrapy框架基于CrawlSpider的全站数据爬取

    引入 提问:如果想要通过爬虫程序去爬取”糗百“全站数据新闻数据的话,有几种实现方法? 方法一:基于Scrapy框架中的Spider的递归爬取进行实现(Request模块递归回调parse方法). 方法 ...

  3. Python+Scrapy+Crawlspider 爬取数据且存入MySQL数据库

    1.Scrapy使用流程 1-1.使用Terminal终端创建工程,输入指令:scrapy startproject ProName 1-2.进入工程目录:cd ProName 1-3.创建爬虫文件( ...

  4. 一个scrapy框架的爬虫(爬取京东图书)

    我们的这个爬虫设计来爬取京东图书(jd.com). scrapy框架相信大家比较了解了.里面有很多复杂的机制,超出本文的范围. 1.爬虫spider tips: 1.xpath的语法比较坑,但是你可以 ...

  5. scrapy框架综合运用 爬取天气预报 + 定时任务

    爬取目标网站: http://www.weather.com.cn/ 具体区域天气地址: http://www.weather.com.cn/weather1d/101280601.shtm(深圳) ...

  6. Scrapy 框架 使用 selenium 爬取动态加载内容

    使用 selenium 爬取动态加载内容 开启中间件 DOWNLOADER_MIDDLEWARES = { 'wangyiPro.middlewares.WangyiproDownloaderMidd ...

  7. 信息技术手册可视化进度报告 基于BeautifulSoup框架的python3爬取数据并连接保存到MySQL数据库

    老师给我们提供了一个word文档,里面是一份信息行业热词解释手册,要求我们把里面的文字存进数据库里面,然后在前台展示出来. 首先面临的问题是怎么把数据导进MySQL数据库,大家都有自己的方法,我采用了 ...

  8. Scrapy持久化存储-爬取数据转义

    Scrapy持久化存储 爬虫爬取数据转义问题 使用这种格式,会自动帮我们转义 'insert into wen values(%s,%s)',(item['title'],item['content' ...

  9. Python使用Scrapy框架爬取数据存入CSV文件(Python爬虫实战4)

    1. Scrapy框架 Scrapy是python下实现爬虫功能的框架,能够将数据解析.数据处理.数据存储合为一体功能的爬虫框架. 2. Scrapy安装 1. 安装依赖包 yum install g ...

随机推荐

  1. 类的命名空间与卸载详解及jvisualvm使用

    类的命名空间详解: 在上一次[https://www.cnblogs.com/webor2006/p/9108301.html]最后实验中有一个违背咱们理解的,这里回顾一下: 也就是说,"某 ...

  2. 08—mybatis注解配置二

    动态sql mybatis的注解也支持动态sql.mybatis提供了各种注解,如@InsertProvider.@UpdateProvider.@DeleteProvider和@SelectProv ...

  3. RAID 10是将RAID 1和RAID 0结合

    RAID 10是将RAID 1和RAID 0结合,它的优点是同时拥有RAID 0的超凡速度和RAID 1的数据高可靠性,但是CPU占用率同样也更高,而且磁盘的利用率比较低.由于利用了RAID 0极高的 ...

  4. HDU 6088 - Rikka with Rock-paper-scissors | 2017 Multi-University Training Contest 5

    思路和任意模数FFT模板都来自 这里 看了一晚上那篇<再探快速傅里叶变换>还是懵得不行,可能水平还没到- - 只能先存个模板了,这题单模数NTT跑了5.9s,没敢写三模数NTT,可能姿势太 ...

  5. Codeforces Round #456 (Div. 2) 912D D. Fishes

    题: OvO http://codeforces.com/contest/912/problem/D 解: 枚举每一条鱼,每放一条鱼,必然放到最优的位置,而最优位置即使钓上的概率最大的位置,即最多的r ...

  6. IVIEW组件Table中加入EChart柱状图

    展示图如下: 主要利用了render函数和updated()钩子函数进行数据填充与渲染. 1.在Table的Colums中加入 1 { 2 title: '比例图', 3 align: 'center ...

  7. P4779 【模板】单源最短路径(标准版)题解

    原题链接 https://www.luogu.org/problemnew/show/P4779 若还未食用弱化版的同学请先做这个qwq https://www.luogu.org/problemne ...

  8. Mybatis源码学习之资源加载(六)

    类加载器简介 Java虚拟机中的类加载器(ClassLoader)负责加载来自文件系统.网络或其他来源的类文件.Java虚拟机中的类加载器默认使用的是双亲委派模式,如图所示,其中有三种默认使用的类加载 ...

  9. Jmeter在一次进程中如何循环执行某个步骤

    在使用Jmeret工具过程中比如我使用借款功能,如果想多借几次就需要一次次执行脚本,如果我在脚本执行过程中登陆一次,可以重复执行借款这一个操作那么就方便多了 于是就用到(循环控制器)这个功能 1.我需 ...

  10. linux查看当前目录

    查看当前路径命令:pwd pwd命令能够显示当前所处的路径. 这个命令比较简单,如果有时在操作过程中忘记了当前的路径,则可以通过此命令来查看路径,其执行方式为: