爬虫2.1-scrapy框架-两种爬虫对比
scrapy框架-两种爬虫对比和大概流程
注:spider.py指使用命令行创建的爬虫主文件
1. 传统spider爬虫
创建scrapy项目,首先进入想创建项目的目录,然后cmd输入:
scrapy startproject projectname # projectname 即是项目名
cd projectname
scrapy genspider spidername “xxxx.com”
spidername就是爬虫文件名 xxxx.com 用于限定爬虫爬取的范围爬虫名,其与项目名不能相同
为了方便运行,之间在project目录下创建start_project.py 来运行整个项目
~start_project.py
from scrapy import cmdline
cmdline.execute("scrapy crawl qsbk_spider".split())
简单两句话,要使用.split()是因为这里参数值接收列表,分裂之后恰好是列表,然后才能被执行。
回到spider.py(爬虫主要模块,用于解析),这里已经帮我们自动生成了一些参数,在parse函数中,response参数使用xpath语法,得到的是SelectorList类的对象(该类是scrapy框架定义的),然后可以使用for语句遍历其中,获得Selector类,还是可以使用xpath语法获取数据,这里由一个很方便的函数.get() 直接获取字符串,再使用.strip()可以直接获取没有空格换行等的文本。
示例代码
def parse(self, response):
contentLeft = response.xpath("//div[@class='col1']/div")
for content in contentLeft:
author = content.xpath(".//h2/text()").get().strip() # get 方法获取Selector中的第一个文本 返回str类型 getall方法获取Selector中的所有文本 返回一个列表
joke = content.xpath(".//div[@class='content']/span/text()").get().strip()
info = XXItem(author=author, joke=joke)
yield info # 推送到piplines.py中进行下一步的数据存入操作
2. crawl型爬虫
在cmd中创建项目和爬虫
scrapy startproject projectname
cd projectname
scrapy genspider -t crawl spidername "domain_name"
可见创建爬虫时便与传统spider不同,然后进入spider.py
# 项目名为wxapp,爬虫名为wxapp_spider.py
from scrapy.linkextractors import LinkExtractor
from scrapy.spiders import CrawlSpider, Rule
from wxapp.items import WxappItem # 导入items中定义好的数据类,方便json格式写入
class WxappSpiderSpider(CrawlSpider):
name = 'wxapp_spider'
allowed_domains = ['wxapp-union.com']
start_urls = ['http://www.wxapp-union.com/portal.php?mod=list&catid=2&page=1'] # 从第一页开始
rules = (
# Rule 1用于从开始页面向后面找到相同模式的url,所以follw选择True,
Rule(LinkExtractor
(allow=r'.+mod=list&catid=2&page=\d+'), follow=True),
# Rule 2用于在Rule 1模式的页面下,找到真正需要解析数据的url,回调函数一定要改名字。
Rule(LinkExtractor(allow=r'.+/article-.+\.html'), callback='parse_info', follow=False),)
def parse_info(self, response):
title = response.xpath(r"//h1[@class='ph']/text()").get() #获取标题
author = response.xpath(r"//p[@class='authors']/a/text()").get() # 获取作者
contents = response.xpath(r"//td[@id='article_content']//text()").getall()
# 获取内容 因为td下面还有很多标签所以要用//text() 之后再.getall()
content = ''.join(contents).strip()
# 巧妙用法 join将列表中的每一项依次放入 加上.strp() 去掉多余的换行和空格
info = WxappItem(title=title, author=author, content=content) #创建info对象
yield info # 推送给pipelines.py
在多个规则下,一定要注意callback和follow参数,判断需要在新的页面中继续跟进符合正则的url。
比如获取职位简介列表的url就需要跟进,而职位的详情页面找到相同的url时不需要跟进,按照职位列表往下遍历即可。
所以,crawl型爬虫适合于整站爬取,传统spider型爬虫适合小规模爬取
crawl型爬虫参数讲解
另外需要使用 LinkExtractors链接提取器:
class scrapy.linkextractors.LinkExtractor(
allow = (),
deny = (),
allow_domains = (),
deny_domains = (),
deny_extensions = None,
restrict_xpaths = (),
tags = ('a','area'),
attrs = ('href'),
canonicalize = True,
unique = True,
process_value = None
)
主要参数讲解:
allow:允许的url。所有满足这个正则表达式的url都会被提取。
deny:禁止的url。所有满足这个正则表达式的url都不会被提取。
allow_domains:允许的域名。只有在这个里面指定的域名的url才会被提取。
deny_domains:禁止的域名。所有在这个里面指定的域名的url都不会被提取。
restrict_xpaths:严格的xpath。和allow共同过滤链接。
Rule规则类:
定义爬虫的规则类。以下对这个类做一个简单的介绍:
class scrapy.spiders.Rule(
link_extractor,
callback = None,
cb_kwargs = None,
follow = None,
process_links = None,
process_request = None
)
主要参数讲解:
link_extractor:一个LinkExtractor对象,用于定义爬取规则。
callback:满足这个规则的url,应该要执行哪个回调函数。因为CrawlSpider使用了parse作为回调函数,因此不要覆盖parse作为回调函数自己的回调函数。
follow:指定根据该规则从response中提取的链接是否需要跟进。
process_links:从link_extractor中获取到链接后会传递给这个函数,用来过滤不需要爬取的链接。
3. 循环页面请求
找到循环条件和结束标准
在spider.py中
def parse(self, response):
...
设置好迭代退出的条件
使用yield scrapy.Request(url, callback=self.parse) 重复调用
示例:
def parse(self, response):
..... # 解析数据的函数
next_url = response.xpath("//ul[@class='pagination']/li[last()]/a/@href").get()
if re.match(r'/\w*/\w*/\d*/', next_url) is None:
return
else:
yield scrapy.Request(self.base_domain+next_url, callback=self.parse)
# 这里 self.base_domain+next_url 就是下一个页面的url,之后回调函数使用它自己,到了最后一页处理完数据 达成if判断条件退出。这里用正则实际上由装逼的意思,判断一下长度就可以了
4. scrapy框架爬虫的大致流程
使用命令行创建爬虫项目
>> scrapy startproject [projectname]
>> cd [projectname]
>> scrapy genspider -t crawl [爬虫名字] [域名] or scrapy genspider [爬虫名字] [域名]
使用IDE打开项目,并在projectname下创建start.py用于启动整个项目,注意scrapy框架只能这样启动。
~ start.py
from scrapy import cmdline
cmdline.execute('scrapy crawl [爬虫名字]'.split())
修改[spidername].py
按需求修改解析函数,如果是crawl型爬虫还需要修改和添加Rule
修改items.py
将需要的参数写好
示例:
class xxItem(scrapy.Item):
author = scrapy.Field()
joke = scrapy.Field()
修改pipelines.py
pipelines.py主要用于按需求存储数据。
看需求是否修改或添加中间件---middlewares.py。
最后按照需求修改settings.py
settings.py
修改ROBOTSTXT_OBEY = False
打开headers DEFAULT_REQUEST_HEADERS 加入User-Agent Cookie
打开并修改piplines设置 ITEM_PIPELINES
打开延时 DOWNLOAD_DELAY
打开中间件 DOWNLOADER_MIDDLEWARES
实战代码可以看另一个笔记:scrapy框架-图片分类下载
爬虫2.1-scrapy框架-两种爬虫对比的更多相关文章
- Python爬虫进阶之Scrapy框架安装配置
Python爬虫进阶之Scrapy框架安装配置 初级的爬虫我们利用urllib和urllib2库以及正则表达式就可以完成了,不过还有更加强大的工具,爬虫框架Scrapy,这安装过程也是煞费苦心哪,在此 ...
- 第三百三十五节,web爬虫讲解2—Scrapy框架爬虫—豆瓣登录与利用打码接口实现自动识别验证码
第三百三十五节,web爬虫讲解2—Scrapy框架爬虫—豆瓣登录与利用打码接口实现自动识别验证码 打码接口文件 # -*- coding: cp936 -*- import sys import os ...
- 第三百三十四节,web爬虫讲解2—Scrapy框架爬虫—Scrapy爬取百度新闻,爬取Ajax动态生成的信息
第三百三十四节,web爬虫讲解2—Scrapy框架爬虫—Scrapy爬取百度新闻,爬取Ajax动态生成的信息 crapy爬取百度新闻,爬取Ajax动态生成的信息,抓取百度新闻首页的新闻rul地址 有多 ...
- 第三百三十三节,web爬虫讲解2—Scrapy框架爬虫—Scrapy模拟浏览器登录—获取Scrapy框架Cookies
第三百三十三节,web爬虫讲解2—Scrapy框架爬虫—Scrapy模拟浏览器登录 模拟浏览器登录 start_requests()方法,可以返回一个请求给爬虫的起始网站,这个返回的请求相当于star ...
- 第三百三十二节,web爬虫讲解2—Scrapy框架爬虫—Scrapy使用
第三百三十二节,web爬虫讲解2—Scrapy框架爬虫—Scrapy使用 xpath表达式 //x 表示向下查找n层指定标签,如://div 表示查找所有div标签 /x 表示向下查找一层指定的标签 ...
- 第三百三十一节,web爬虫讲解2—Scrapy框架爬虫—Scrapy安装—Scrapy指令
第三百三十一节,web爬虫讲解2—Scrapy框架爬虫—Scrapy安装—Scrapy指令 Scrapy框架安装 1.首先,终端执行命令升级pip: python -m pip install --u ...
- scrapy爬虫提取网页链接的两种方法以及构造HtmlResponse对象的方式
Response对象的几点说明: Response对象用来描述一个HTTP响应,Response只是一个基类,根据相应的不同有如下子类: TextResponse,HtmlResponse,XmlRe ...
- Python爬虫知识点四--scrapy框架
一.scrapy结构数据 解释: 1.名词解析: o 引擎(Scrapy Engine)o 调度器(Scheduler)o 下载器(Downloader)o 蜘蛛(Spiders)o 项目管 ...
- 爬虫基础(五)-----scrapy框架简介
---------------------------------------------------摆脱穷人思维 <五> :拓展自己的视野,适当做一些眼前''无用''的事情,防止进入只关 ...
随机推荐
- C# abstract,virtual 修饰符
abstract(抽象):该abstract修饰符指示要修改的东西有缺失或不完整的实现.abstract修饰符可以与类,方法,属性,索引器和事件一起使用.abstract在类声明中使用修饰符来指示类仅 ...
- 集合异常之Set接口
Set接口,它里面的集合,所存储的元素就是不重复的,通过元素的equals方法,来判断是否为重复元素. HashSet存储JavaAPI中的类型元素 给HashSet中存储JavaAPI中提供的类型元 ...
- dataTable学习心得
1.引用文件 <link rel="stylesheet" href="https://cdn.datatables.net/1.10.16/css/jquery. ...
- 竞赛题解 - Palisection(CF-17E)
Palisection(CF-17E) - 竞赛题解 Manacher学到一定程度,也需要练一下有趣的题了-- (这是多老的题了 \(QwQ\))[传送门] 『题意』 给出一个字符串,求总共有多少对不 ...
- iOS 12 真机调试 Xcode 9 提示 Could not locate device support files.
升级 iOS 12 之后,使用 Xcode 9 真机调试会提示错误: Could not locate device support files. This iPhone 6 Plus is runn ...
- H5混合开发进阶之inspect调试
h5界面嵌套在原生app内部的时候,需要调用原生的方法,传递数据.中间难以调试代码,. 用google的 inspect调试.查看数据的传输方式. 1.adb连接正常,打开手机USB调试 2.第一次使 ...
- 安装 vue-devtools
1. github下载 vue-devtools: git clone https://github.com/vuejs/vue-devtools 2. node install 安装包 3. vi ...
- st link 连接问题ST LINK is not in the DFU mode plesse restart it
原因:插上st link后做了一些操作才点击升级.如点击了连接stlink,如下图等: 解决办法: 1. 拔掉stlink 2. 插上stlink 3. 不要点其他的,直接点击ST-LINK-> ...
- 树莓派编译程序时报错:virtual memory exhausted: Cannot allocate memory
一.原因分析: 树莓派内存太小,编译程序会出现virtual memory exhausted: Cannot allocate memory的问题,可以用swap扩展内存的方法. 二.解决方法: 安 ...
- verilog中参数传递与参数定义中#的作用(二)
一.module内部有效的定义 用parameter来定义一个标志符代表一个常量,称作符号常量,他可以提高程序的可读性和可维护性.parameter是参数型数据的关键字,在每一个赋值语句的右边都必须是 ...