咨询热线:18580786066 联系人:郭佳宏 地址:周市镇新镇路698号
网络爬虫之scrapy框架详解
来源:优德88登录 发布时间:2019-11-14 点击量:308
twisted介绍
Twisted是用Python实现的基于事件驱动的网络引擎框架,scrapy正是依赖于twisted,
从而基于事件循环机制实现爬虫的并发。
scrapy的pipeline文件和items文件
这两个文件有什么作用
先看看我们上篇的示例:
# -*- coding: utf-8 -*-import scrapy class ChoutiSpider(scrapy.Spider): """ 爬去抽屉网的帖子信息 """ name = "chouti" allowed_domains = ["chouti.com"] start_urls = ["http://chouti.com/"] def parse(self, response): # 获取帖子列表的父级div content_div = response.xpath("//div[@id="content-list"]") # 获取帖子item的列表 items_list = content_div.xpath(".//div[@]") # 打开一个文件句柄,目的是为了将获取的东西写入文件 with open("articles.log","a+",encoding="utf-8") as f: # 循环item_list for item in items_list: # 获取每个item的第一个a标签的文本和url链接 text = item.xpath(".//a/text()").extract_first() href = item.xpath(".//a/@href").extract_first() # print(href, text.strip()) # print("-"*100) f.write(href+"") f.write(text.strip()+"") f.write("-"*100+"") # 获取分页的页码,然后让程序循环爬去每个链接 # 页码标签对象列表 page_list = response.xpath("//div[@id="dig_lcpage"]") # 循环列表 for page in page_list: # 获取每个标签下的a标签的url,即每页的链接 page_a_url = page.xpath(".//a/@href").extract() # 将域名和url拼接起来 page_url = "https://dig.chouti.com" + page_a_url # 重要的一步!!!! # 导入Request模块,然后实例化一个Request对象,然后yield它 # 就会自动执行Request对象的callback方法,爬去的是url参数中的链接 from scrapy.http import Request yield Request(url=page_url,callback=self.parse)
在这个示例中,虽然我们已经通过chouti.py一个文件中的parse方法实现了爬去抽屉网的新闻并将之保存在文件中的功能,
但是我们会发现有两个问题:
1、在循环爬去每一页的时候,每次都需要重新打开然后再关闭文件,如果数据量庞大的话,这对性能有很大的影响。
2、我们将解析和数据持久化都放在了同一个文件的同一个方法中,没有做到分工明确
如果要解决这两个问题,则需要用到scrapy自动为我们生成的pipeline文件和items文件
这两个文件怎么用
如果我们要使用这两个文件从而解决问题,则需要有四部操作:
a.编写pipeline文件中的类,格式如下:
class XXXPipeline(object):def process_item(self, item, spider):return item
b.编写items文件中的类,格式如下:
class XXXItem(scrapy.Item):href = scrapy.Field()title = scrapy.Field()
c.配置settings文件
ITEM_PIPELINES = { "xxx.pipelines.XXXPipeline": 300, # "xxx.pipelines.XXXPipeline2": 600, # 后面的数字为优先级,数字越大,优先级月底}
d.在parse方法中yield一个Item对象
from xxx.items import XXXItemdef parse(self, response): ... yield XXXItem(text=text,href=href)
执行流程为:
当我们在执行爬虫中的parse方法的时候,scrapy一旦解析到有yield XXXitem的语句,就会到配置文件中找
ITEM_PIPELINES的配置项,进而找到XXXPipeline类,然后执行其中的方法,我们就可以在方法中做很多操作
当然,pipeline中不止process_item一个方法。
Pipeline中的方法详解
class FilePipeline(object):def __init__(self,path):self.f = Noneself.path = path@classmethoddef from_crawler(cls, crawler):"""初始化时候,用于创建pipeline对象:param crawler::return:""" # 从配置文件中获取配置好的文件存放目录path = crawler.settings.get("HREF_FILE_PATH")return cls(path)def open_spider(self,spider):"""爬虫开始执行时,调用:param spider::return:"""self.f = open(self.path,"a+")def process_item(self, item, spider):# 在这里做持久化self.f.write(item["href"]+"")return item # 交给下一个pipeline的process_item方法# raise DropItem()# 如果写上这一句,后续的 pipeline的process_item方法不再执行def close_spider(self,spider):"""爬虫关闭时,被调用:param spider::return:"""self.f.close()
去重
scrapy内部实现的去重
从上一篇的例子我们可以看出,其实scrapy内部在循环爬去页码的时候,已经帮我们做了去重功能的,
因为我们在首页可以看到1,2,3,4,5,6,7,8,9,10页的页码以及连接,当爬虫爬到第二页的时候,
还是可以看到这10个页面及连接,然后它并没有再重新把第一页爬一遍。
它内部实现去重的原理是,将已爬去的网址存入一个set集合里,每次爬取新页面的时候就先看一下是否在集合里面
如果在,就不再爬去,如果不在就爬取,然后再添加入到set里。当然,这个集合存放的不是原网址,
而是将链接通过request_fingerprint()方法将它变成一个类似于md5的值,这样可以节省存储空间
自定义去重
虽然scrapy已经帮我们实现了去重,但是有时候不足以满足我们的需求,这样就需要我们自定义去重了
自定义去重分两步
1、编写DupeFilter类
from scrapy.dupefilter import BaseDupeFilterfrom scrapy.utils.request import request_fingerprintclass XXXDupeFilter(BaseDupeFilter):def __init__(self):"""初始化一个集合,用来存放爬去过的网址"""self.visited_fd = set()@classmethoddef from_settings(cls, settings):"""如果我们自定义了DupeFilter类并且重写了父类的该方法,scrapy会首先执行该方法,获取DupeFilter对象,如果没有定义,则会执行init方法来获取对象"""return cls()def request_seen(self, request):"""在此方法中做操作,判断以及添加网址到set里"""# 将request里的url转换下,然后判断是否在set里fd = request_fingerprint(request=request)# 循环set集合,如果已经在集合里,则返回True,爬虫将不会继续爬取该网址if fd in self.visited_fd:return Trueself.visited_fd.add(fd)def open(self): # can return deferred"""开始前执行此方法"""print("开始")def close(self, reason): # can return a deferred"""结束后执行此方法"""print("结束")def log(self, request, spider): # log that a request has been filtered"""在此方法中可以做日志操作""" print("日志")
2.配置settings文件
# 修改默认的去重规则# DUPEFILTER_CLASS = "scrapy.dupefilter.RFPDupeFilter"DUPEFILTER_CLASS = "xxx.dupefilters.XXXDupeFilter"
深度
深度就是爬虫所要爬取的层级
限制深度只需要配置一下即可
# 限制深度DEPTH_LIMIT = 3
cookie
获取上一次请求之后获得的cookie
from scrapy.http.cookies import CookieJarclass ChoutiSpider(scrapy.Spider): name = "chouti" allowed_domains = ["chouti.com"] start_urls = ["https://dig.chouti.com/"] cookie_dict = {} def parse(self, response): # 去响应头中获取cookie,cookie保存在cookie_jar对象 cookie_jar = CookieJar() cookie_jar.extract_cookies(response, response.request) # 去对象中将cookie解析到字典 for k, v in cookie_jar._cookies.items(): for i, j in v.items(): for m, n in j.items(): self.cookie_dict[m] = n.value
再次请求的时候携带cookie
yield Request( url="https://dig.chouti.com/login", method="POST", body="phone=861300000000&password=12345678&oneMonth=1",# cookies=self.cookie_dict, headers={ "Content-Type": "application/x-www-form-urlencoded; charset=UTF-8" }, callback=self.check_login )
相关产品
-
湄公河三角洲也是盛产大米的地方,在距离一个多小时车程的胡志明市的远郊,一家小型的家庭食品加工厂生产的春卷皮(rice paper)、面条,原料便全部来自湄公河三角洲。
-
中新网北京12月4日电(记者 王牧青)3日,2017年丰台区中小学生班级3X3篮球联赛在华熙LIVE·五棵松HI-PARK落幕。最终,男子高中组冠军被北京十中收入囊中,北京十二中获男子初中组冠军,小学男子甲组和乙组冠军分别为北京小学万年花城分校和大红门一小。
-
党的十八大向全党提出了谆谆告诫:面对人民的信任和重托,面对新的历史条件和考验,全党必须增强忧患意识,谦虚谨慎,戒骄戒躁,始终保持清醒头脑;必须增强创新意识,坚持真理,修正错误,始终保持奋发有为的精神状态;必须增强宗旨意识,相信群众,依靠群众,始终把人民放在心中最高位置;必须增强使命意识,求真务实,艰苦奋斗,始终保持共产党人的政治本色。
-
如果说万隆会议是唤醒民族觉醒和增强殖民地、半殖民地和弱小国家的团结独立的伟大事件,那么,“一带一路”则是当今世界人民共创、共享合作发展机遇,推动经济繁荣和人类进步的伟大创举,是万隆精神的继承、发展和创新。
-
水是生命之源。浙江因水而名,因水而美,因水而兴。省委十三届四次全会提出“五水(污水、洪水、涝水、供水和节水)共治”决策,明确要以治水为突破口,推进结构调整与产业升级。
-
事发后,双方就赔偿事宜产生争议,后经巢湖市医患纠纷人民调解委员会调解,双方一致同意委托安徽某司法鉴定所进行鉴定。
-
欧米德·柯德斯塔尼是谷歌第12名员工,现为谷歌两位创始人的高级顾问。他在纽约曼哈顿中央公园拥有一套公寓,这也是世界上最贵的地段之一。这套公寓共有4个卧室、6个卫生间,以及一个405平方英尺的露天阳台。柯德斯塔尼买它时花了2950万美元。
-
Razer(雷蛇)今日携手腾讯游戏发布了Razer DeathAdder炼狱蝰蛇3500《穿越火线》金典版游戏鼠标。该款鼠标目前正在http://cf.razerzone.com 劲爆促销中,即日起至3月20日买就送118QB穿越火线大礼包哟!(烟雾头盔、VIP会员、团队爆破包 三十天)
热点资讯
- 彭博社:小米IPO发行价偏低,部分早期投资者或面临亏损2019-06-23
- 英特尔基带VS高通基带:苹果iPhoneXS优于iPhoneX,却不敌三星GalaxyNote92019-11-07
- 谷歌WaymoCEO:无人车推广不会一帆风顺2019-11-06
- 新瑞金城:1260年黄金攀升前期交易黄金运营策略分析|新浪石油财经2019-11-05
- K리그1강원,내셔널리그김해시청에덜미…이변속출FA컵32강2019-11-05
- 《圣歌》没有开箱:发售后所有故事DLC都是免费2019-06-23
- 网络主播漂泊几万公里两年内帮50多人找回家路2019-10-29
- TFBOY,没有S2019-11-05