Python基础之Scrapy简介

Scrapy作为爬虫的进阶内容,可以实现多线程爬取目标内容,简化代码逻辑,提高开发效率,深受爬虫开发者的喜爱,本文主要以爬取某股票网站为例,简述如何通过Scrapy实现爬虫,仅供学习分享使用,如有不足之处,还请指正。

什么是Scrapy?

Scrapy是用python实现的一个为了爬取网站数据,提取结构性数据而编写的应用框架。使用Twisted高效异步网络框架来处理网络通信。Scrapy架构:

 

关于Scrapy架构各项说明,如下所示:

  • ScrapyEngine:引擎。负责控制数据流在系统中所有组件中流动,并在相应动作发生时触发事件。 此组件相当于爬虫的“大脑”,是 整个爬虫的调度中心。 
  • Schedule:调度器。接收从引擎发过来的requests,并将他们入队。初始爬取url和后续在页面里爬到的待爬取url放入调度器中,等待被爬取。调度器会自动去掉重复的url。
  • Downloader:下载器。负责获取页面数据,并提供给引擎,而后提供给spider。
  • Spider:爬虫。用户编些用于分析response并提取item和额外跟进的url。将额外跟进的url提交给ScrapyEngine,加入到Schedule中。将每个spider负责处理一个特定(或 一些)网站。 
  • ItemPipeline:负责处理被spider提取出来的item。当页面被爬虫解析所需的数据存入Item后,将被发送到Pipeline,并经过设置好次序
  • DownloaderMiddlewares:下载中间件。是在引擎和下载器之间的特定钩子(specific hook),处理它们之间的请求(request)和响应(response)。提供了一个简单的机制,通过插入自定义代码来扩展Scrapy功能。通过设置DownloaderMiddlewares来实现爬虫自动更换user-agent,IP等。
  • SpiderMiddlewares:Spider中间件。是在引擎和Spider之间的特定钩子(specific hook),处理spider的输入(response)和输出(items或requests)。提供了同样简单机制,通过插入自定义代码来扩展Scrapy功能。

Scrapy数据流:

  1. ScrapyEngine打开一个网站,找到处理该网站的Spider,并向该Spider请求第一个(批)要爬取的url(s);
  2. ScrapyEngine向调度器请求第一个要爬取的url,并加入到Schedule作为请求以备调度;
  3. ScrapyEngine向调度器请求下一个要爬取的url;
  4. Schedule返回下一个要爬取的url给ScrapyEngine,ScrapyEngine通过DownloaderMiddlewares将url转发给Downloader;
  5. 页面下载完毕,Downloader生成一个页面的Response,通过DownloaderMiddlewares发送给ScrapyEngine;
  6. ScrapyEngine从Downloader中接收到Response,通过SpiderMiddlewares发送给Spider处理;
  7. Spider处理Response并返回提取到的Item以及新的Request给ScrapyEngine;
  8. ScrapyEngine将Spider返回的Item交给ItemPipeline,将Spider返回的Request交给Schedule进行从第二步开始的重复操作,直到调度器中没有待处理的Request,ScrapyEngine关闭。

Scrapy安装

在命令行模式下,通过pip install scrapy命令进行安装Scrapy,如下所示:

当出现以下提示信息时,表示安装成功

 

Scrapy创建项目

在命令行模式下,切换到项目存放目录,通过scrapy startproject stockstar 创建爬虫项目,如下所示:

根据提示,通过提供的模板,创建爬虫【命令格式:scrapy genspider 爬虫名称 域名】,如下所示:

注意:爬虫名称,不能跟项目名称一致,否则会报错,如下所示:

通过Pycharm打开新创建的scrapy项目,如下所示:

爬取目标

本例主要爬取某证券网站行情中心股票ID与名称信息,如下所示:

Scrapy爬虫开发

通过命令行创建项目后,基本Scrapy爬虫框架已经形成,剩下的就是业务代码填充。

item项定义

定义需要爬取的字段信息,如下所示:

1 class StockstarItem(scrapy.Item):
2     """
3     定义需要爬取的字段名称
4     5     # define the fields for your item here like:
6      name = scrapy.Field()
7     stock_type = scrapy.Field()   股票类型
8     stock_id = scrapy.Field()   股票ID
9     stock_name = scrapy.Field()   股票名称

定制爬虫逻辑

Scrapy的爬虫结构是固定的,定义一个类,继承自scrapy.Spider,类中定义属性【爬虫名称,域名,起始url】,重写父类方法【parse】,根据需要爬取的页面逻辑不同,在parse中定制不同的爬虫代码,如下所示:

 1  StockSpider(scrapy.Spider):
 2     name = 'stock'
 3     allowed_domains = [quote.stockstar.com']   域名
 4     start_urls = [http://quote.stockstar.com/stock/stock_index.htm 启动的url
 5 
 6     def parse(self,response):
 7          8         解析函数
 9         :param response:
10         :return:
11         12         item = StockstarItem()
13         styles = [沪A',沪B深A深B']
14         index = 0
15         for style in styles:
16             print(********************本次抓取' + style[index] + 股票********************)
17             ids = response.xpath(
18                 //div[@class="w"]/div[@class="main clearfix"]/div[@class="seo_area"]/div[19                 @class="seo_keywordsCon"]/ul[@id="index_data_' + str(index) + "]/li/span/a/text()).getall()
20             names =21                 22                 "]/li/a/text()23              print('ids = '+str(ids))
24              print('names = ' + str(names))
25             for i  range(len(ids)):
26                 item[stock_type'] = style
27                 item[stock_id str(ids[i])
28                 item[stock_name str(names[i])
29                 yield item

数据处理

在Pipeline中,对抓取的数据进行处理,本例为简便,在控制进行输出,如下所示:

 StockstarPipeline:
2      process_item(self,item,spider):
3         股票类型>>>>'+item[']+股票代码>>>>股票名称>>>>])
4         return item

注意:在对item进行赋值时,只能通过item['key']=value的方式进行赋值,不可以通过item.key=value的方式赋值。

Scrapy配置

通过settings.py文件进行配置,包括请求头,管道,robots协议等内容,如下所示:

 Scrapy settings for stockstar project
 2 #
 3  For simplicity,this file contains only settings considered important or
 4  commonly used. You can find more settings consulting the documentation:
 5  6      https://docs.scrapy.org/en/latest/topics/settings.html
 7      https://docs.scrapy.org/en/latest/topics/downloader-middleware.html
 8      https://docs.scrapy.org/en/latest/topics/spider-middleware.html
 9 
10 BOT_NAME = stockstar11 
12 SPIDER_MODULES = [stockstar.spiders13 NEWSPIDER_MODULE = 14 
15 
16  Crawl responsibly by identifying yourself (and your website) on the user-agent
17 USER_AGENT = 'stockstar (+http://www.yourdomain.com)'
18 
19  Obey robots.txt rules 是否遵守robots协议
20 ROBOTSTXT_OBEY = False
21 
22  Configure maximum concurrent requests performed by Scrapy (default: 16)
23 CONCURRENT_REQUESTS = 32
24 
25  Configure a delay for requests for the same website (default: 0)
26  See https://docs.scrapy.org/en/latest/topics/settings.html#download-delay
27  See also autothrottle settings and docs
28 DOWNLOAD_DELAY = 3
29  The download delay setting will honor only one of:
30 CONCURRENT_REQUESTS_PER_DOMAIN = 16
31 CONCURRENT_REQUESTS_PER_IP = 16
32 
33  Disable cookies (enabled by default)
34 COOKIES_ENABLED = False
35 
36  Disable Telnet Console (enabled by default)
37 TELNETCONSOLE_ENABLED = False
38 
39  Override the default request headers:
40 DEFAULT_REQUEST_HEADERS = {
41    'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
42   User-Agent': Mozilla/5.0 (Linux; Android 6.0; Nexus 5 Build/MRA58N) AppleWebKit/537.36 (KHTML,like Gecko) Chrome/92.0.4515.131 Mobile Safari/537.36' ,1)">43    'Accept-Language': 'en,zh-CN,zh;q=0.9'
44 }
45 
46  Enable or disable spider middlewares
47  See https://docs.scrapy.org/en/latest/topics/spider-middleware.html
48 SPIDER_MIDDLEWARES = {
49     'stockstar.middlewares.StockstarSpiderMiddleware': 543,1)">50 }
51 
52  Enable or disable downloader middlewares
53  See https://docs.scrapy.org/en/latest/topics/downloader-middleware.html
54 DOWNLOADER_MIDDLEWARES = {
55     'stockstar.middlewares.StockstarDownloaderMiddleware': 543,1)">56 57 
58  Enable or disable extensions
59  See https://docs.scrapy.org/en/latest/topics/extensions.html
60 EXTENSIONS = {
61     'scrapy.extensions.telnet.TelnetConsole': None,1)">62 63 
64  Configure item pipelines
65  See https://docs.scrapy.org/en/latest/topics/item-pipeline.html
66 ITEM_PIPELINES =67    stockstar.pipelines.StockstarPipeline': 30068 69 
70  Enable and configure the AutoThrottle extension (disabled by default)
71  See https://docs.scrapy.org/en/latest/topics/autothrottle.html
72 AUTOTHROTTLE_ENABLED = True
73  The initial download delay
74 AUTOTHROTTLE_START_DELAY = 5
75  The maximum download delay to be set in case of high latencies
76 AUTOTHROTTLE_MAX_DELAY = 60
77  The average number of requests Scrapy should be sending in parallel to
78  each remote server
79 AUTOTHROTTLE_TARGET_CONCURRENCY = 1.0
80  Enable showing throttling stats for every response received:
81 AUTOTHROTTLE_DEBUG = False
82 
83  Enable and configure HTTP caching (disabled by default)
84  See https://docs.scrapy.org/en/latest/topics/downloader-middleware.html#httpcache-middleware-settings
85 HTTPCACHE_ENABLED = True
86 HTTPCACHE_EXPIRATION_SECS = 0
87 HTTPCACHE_DIR = 'httpcache'
88 HTTPCACHE_IGNORE_HTTP_CODES = []
89 HTTPCACHE_STORAGE = 'scrapy.extensions.httpcache.FilesystemCacheStorage'
View Code

Scrapy运行

因scrapy是各个独立的页面,只能通过终端命令行的方式运行,格式为:scrapy crawl 爬虫名称,如下所示:

1 scrapy crawl stock

如下图所示:

 

备注

本例内容相对简单,仅为说明Scrapy的常见用法,爬取的内容都是第一次请求能够获取到源码的内容,即所见即所得。

遗留两个小问题:

  1. 对于爬取的内容需要翻页才能完成,即多次请求,如何处理?
  2. 对于爬取的内容是异步传输,页面请求只是获取一个框架,内容是异步填充,即常见的ajax方式,如何处理?

以上两个问题,待后续遇到时,再进一步分析。一首陶渊明的归田园居,与君共享。

归园田居(其一)

【作者】陶渊明 【朝代】魏晋
 

少无适俗韵,性本爱丘山。误落尘网中,一去三十年。

羁鸟恋旧林,池鱼思故渊。开荒南际,守拙归园田。

方宅十余亩,草屋八九间。榆柳荫后檐,桃李罗堂前。

暧暧远人村,依依墟里烟。狗吠深巷中,鸡鸣桑树颠。

户庭无尘杂,虚室有余闲。久在樊笼里,复得返自然。

原文地址:https://www.cnblogs.com/hsiang

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Python中的函数(二) 在上一篇文章中提到了Python中函数的定义和使用,在这篇文章里我们来讨论下关于函数的一些更深的话题。在学习C语言函数的时候,遇到的问题主要有形参实参的区别、参数的传递和改变、变量的作用域。同样在Python中,关于对函数的理解和使用也存在这些问题。下面来逐一讲解。一.函
Python中的字符串 可能大多数人在学习C语言的时候,最先接触的数据类型就是字符串,因为大多教程都是以"Hello world"这个程序作为入门程序,这个程序中要打印的"Hello world"就是字符串。如果你做过自然语言处理方面的研究,并且用Python
Python 面向对象编程(一) 虽然Python是解释性语言,但是它是面向对象的,能够进行对象编程。下面就来了解一下如何在Python中进行对象编程。一.如何定义一个类 在进行python面向对象编程之前,先来了解几个术语:类,类对象,实例对象,属性,函数和方法。 类是对现实世界中一些事物的封装,
Python面向对象编程(二) 在前面一篇文章中谈到了类的基本定义和使用方法,这只体现了面向对象编程的三大特点之一:封装。下面就来了解一下另外两大特征:继承和多态。 在Python中,如果需要的话,可以让一个类去继承一个类,被继承的类称为父类或者超类、也可以称作基类,继承的类称为子类。并且Pytho
Python中的函数(一) 接触过C语言的朋友对函数这个词肯定非常熟悉,无论在哪门编程语言当中,函数(当然在某些语言里称作方法,意义是相同的)都扮演着至关重要的角色。今天就来了解一下Python中的函数用法。一.函数的定义 在某些编程语言当中,函数声明和函数定义是区分开的(在这些编程语言当中函数声明
在windows下如何快速搭建web.py开发框架 用Python进行web开发的话有很多框架供选择,比如最出名的Django,tornado等,除了这些框架之外,有一个轻量级的框架使用起来也是非常方便和顺手,就是web.py。它由一名黑客所创建,但是不幸的是这位创建者于2013年自杀了。据说现在由
将Sublime Text 2搭建成一个好用的IDE 说起编辑器,可能大部分人要推荐的是Vim和Emacs,本人用过Vim,功能确实强大,但是不是很习惯,之前一直有朋友推荐SUblime Text 2这款编辑器,然后这段时间就试了一下,就深深地喜欢上这款编辑器了...
Python中的模块 有过C语言编程经验的朋友都知道在C语言中如果要引用sqrt这个函数,必须用语句"#include<math.h>"引入math.h这个头文件,否则是无法正常进行调用的。那么在Python中,如果要引用一些内置的函数,该怎么处理呢?在Python中
Python的基础语法 在对Python有了基础的认识之后,下面来了解一下Python的基础语法,看看它和C语言、java之间的基础语法差异。一.变量、表达式和语句 Python中的语句也称作命令,比如print "hello python"这就是一条语句。 表达式,顾名思义,是
Eclipse+PyDevʽjango+Mysql搭建Python web开发环境 Python的web框架有很多,目前主流的有Django、Tornado、Web.py等,最流行的要属Django了,也是被大家最看好的框架之一。下面就来讲讲如何搭建Django的开发环境。一.准备工作 需要下载的
在windows下安装配置Ulipad 今天推荐一款轻便的文本编辑器Ulipad,用来写一些小的Python脚本非常方便。 Ulipad下载地址: https://github.com/limodou/ulipad http://files.cnblogs.com/dolphin0520/u...
Python中的函数(三) 在前面两篇文章中已经探讨了函数的一些相关用法,下面一起来了解一下函数参数类型的问题。在C语言中,调用函数时必须依照函数定义时的参数个数以及类型来传递参数,否则将会发生错误,这个是严格进行规定的。然而在Python中函数参数定义和传递的方式相比而言就灵活多了。一.函数参数的
在Notepad++中搭配Python开发环境 Python在最近几年一度成为最流行的语言之一,不仅仅是因为它简洁明了,更在于它的功能之强大。它不仅能够完成一般脚本语言所能做的事情,还能很方便快捷地进行大规模的项目开发。在学习Python之前我们来看一下Python的历史由来,"Pytho
Python中的条件选择和循环语句 同C语言、Java一样,Python中也存在条件选择和循环语句,其风格和C语言、java的很类似,但是在写法和用法上还是有一些区别。今天就让我们一起来了解一下。一.条件选择语句 Python中条件选择语句的关键字为:if 、elif 、else这三个。其基本形式如
关于raw_input( )和sys.stdin.readline( )的区别 之前一直认为用raw_input( )和sys.stdin.readline( )来获取输入的效果完全相同,但是最近在写程序时有类似这样一段代码:import sysline = sys.stdin.readline()
初识Python 跟学习所有的编程语言一样,首先得了解这门语言的编程风格和最基础的语法。下面就让我们一起来了解一下Python的编程风格。1.逻辑行与物理行 在Python中有逻辑行和物理行这个概念,物理行是指在编辑器中实际看到的一行,逻辑行是指一条Python语句。在Python中提倡一个物理行只
当我们的代码是有访问网络相关的操作时,比如http请求或者访问远程数据库,经常可能会发生一些错误,有些错误可能重新去发送请求就会成功,本文分析常见可能需要重试的场景,并最后给出python代码实现。
1.经典迭代器 2.将Sentence中的__iter__改成生成器函数 改成生成器后用法不变,但更加简洁。 3.惰性实现 当列表比较大,占内存较大时,我们可以采用惰性实现,每次只读取一个元素到内存。 或者使用更简洁的生成器表达式 4.yield from itertools模块含有大量生成器函数可
本文介绍简单介绍socket的常用函数,并以python-kafka中的源码socketpair为例,来讲解python socket的运用
python实践中经常出现编码相关的异常,大多网上找资料而没有理解原理,导致一次次重复错误。本文对常用Unicode、UTF-8、GB2312编码的原理进行介绍,接着介绍了python字符类型unicode和str以及常见编解码错误UnicodeEncodeError和UnicodeDEcodeEr