Scrapy糗事百科爬虫实战代码分析

视频教学网址:【python爬虫_从入门到精通(高级篇)】scrapy框架、反爬、分布式爬虫

一、Scrapy糗事百科之爬取单页数据并保存

具体的创建方法可以参照上一篇文章Python最火爬虫框架Scrapy入门与实践
创建的目录结构如下:

在qsbk_spider.py文件中,response是一个’scrapy.http.response.html.HtmlResponse’对象.可以执行’xpath’和’css’语法来提取数据。

# -*- coding: utf-8 -*-
import scrapy
from qsbk.items import QsbkItemclass QsbkSpiderSpider(scrapy.Spider):name = 'qsbk_spider'allowed_domains = ['qiushibaike.com']start_urls = ['https://www.qiushibaike.com/text/page/1/']def parse(self, response):# SelectorListduanzidivs =  response.xpath("//div[@class='col1 old-style-col1']/div")# 遍历divfor duanzidiv in duanzidivs:# Selector-->Unicodeauthor =  duanzidiv.xpath(".//a/h2/text()").get().strip()content = duanzidiv.xpath(".//div[@class='content']//text()").getall()content = " ".join(content).strip()# 提取出来的数据,是一个’Selector’或者是一个’SelectorList’对象。如果想要获取其中的字符串,那么应该执行’getall’或是’get’方法# getall方法:获取Selector中的所有文本,返回的是一个列表。get方法:是获取selector中的第一个文本,返回的是str类型.item = QsbkItem(author=author,content=content)#如果数据解析回来,要传给pipline处理.那么可以使用’yield’来返.或是可以收集到所有的item,最后统一使用return返回.yield item

在itmes.py文件中,用来存放爬虫爬取下来的数据类型,里面的数据与qsbk_spider.py 定义的 一 一对应。

import scrapy
# item:建议在item.py中定义好模型.以后就不要使用字典了.在最后将数据变成字典就行了
class QsbkItem(scrapy.Item):author = scrapy.Field()content = scrapy.Field()

在piplines文件中,用来将items的模型存储到本地磁盘中;
pipeline:这个是专门用来保存数据地.其中三个方法是会经常用到的
①open_spider(self,spider):当爬虫被打开的时候就会被调用
②process_item(self,item,spider):当爬虫有item传过来的时候就会被调用
③close_spider(self,spider):当爬虫关闭的时候会被调用
要激活piplilne , 应该在settings.py中设置ITEM_PIPELINES将其激活.

import jsonclass QsbkPipeline(object):def __init__(self):self.fp = open("duanzi.json",'w',encoding="utf-8") # 创建一个导入的对象def open_spider(self,spider):print("爬虫开始了。。")def process_item(self, item, spider):# 将item转换为字典,再将字典转换为json ;item是爬虫返回的数据item_json = json.dumps(dict(item),ensure_ascii=False) # json字符串写入文件当中self.fp.write(item_json+'\n')return itemdef close_spider(self,spider):self.fp.close()print("爬虫结束了。。")

settings.py: 本爬虫的一些配置信息(比如请求头、多久发送一次、ip代理池等等),需要将下面的注释去掉。

# 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/76.0.3809.87 Safari/537.36 SLBrowser/6.0.1.4221'
}# Configure item pipelines
# See https://docs.scrapy.org/en/latest/topics/item-pipeline.html
ITEM_PIPELINES = {'qsbk.pipelines.QsbkPipeline': 300, #值越小优先级越高;当设置多个爬虫时,可以参考此值。
}

由于每一次在命令端调试比较麻烦,可以在qsbk文件的根目录创建start.py文件进行调试。

from scrapy import cmdline
# 调式
cmdline.execute("scrapy crawl qsbk_spider".split())
# cmdline.execute(['scrapy', 'crawl', 'qsbk_spider'])

二、Scrapy糗事百科之优化数据存储方式

在pipelines.py文件里保存json数据的时候,可以使用这两个类,让操作更加简单。
①JsonItemExporter:这个是每次把数据添加到内存中.最后统一写入到磁盘中.
好处就是存储的数据是一个满足json规则的数据.
坏处就是如果数据量比较大,那么比较消耗内存

from scrapy.exporters import JsonItemExporter
class QsbkPipeline(object):def __init__(self):# 二进制打开文件,因为JsonItemExporter是以二进制写入写入的self.fp = open("duanzi.json",'wb')self.exporter = JsonItemExporter(self.fp,ensure_ascii=False,encoding="utf-8")# 开始导入self.exporter.start_exporting()def open_spider(self,spider):print("爬虫开始了。。")def process_item(self, item, spider):# 先把传进来的字典塞到一个列表当中self.exporter.export_item(item)return itemdef close_spider(self,spider):# 完成导入self.exporter.finish_exporting() # 再统一写道json文件中

json文件存储一行数据:

[{"author": "山鹰寂寞飞", "content": "那年那人那山第三十二章:钱去楼空 红军很惊讶的问:“怎么了?是怪我昨天没来接你吗?”秀芬面无表情,眼角泪珠往下飞速滚淌着。   红军凑上前,蹲下握住秀芬的手道:“好了,我知道错了,下次不管再晚,哪怕骑车也过来接你,好不好?”    秀芬触电一般用力拽回自己的手,歇斯底里大叫一句:“你走啊!我不想再看到你!”    红军吓了一跳,见秀芬如此激动,好像真想分手,有点莫名其妙,他盯了秀芬一会,眼见她侧脸昂头,只流泪不再说话,态度相当坚决,思忖一会问:“为什么?总得给我个理由吧?是…因为我没\n…\n \n\n 查看全文"}]......

②JsonLinesItemExporter:这个是每次调用export_item的时候就吧这个item存储到硬盘当中.
坏处是每一个字典是一行,整个文件不是一个满足json格式的文件.
好处就是每次处理数据的时候就直接存储到硬盘当中,这样不会消耗内存,数据也比较安全.

from scrapy.exporters import JsonLinesItemExporter
class QsbkPipeline(object):def __init__(self):# 二进制打开文件,因为JsonItemExporter是以二进制写入写入的self.fp = open("duanzi.json",'wb')self.exporter = JsonLinesItemExporter(self.fp,ensure_ascii=False,encoding="utf-8")def open_spider(self,spider):print("爬虫开始了。。")def process_item(self, item, spider):# 先把传进来的字典塞到一个列表当中self.exporter.export_item(item)return itemdef close_spider(self,spider):self.fp.close()print("爬虫结束了。。")

输出结果:一个字典一行的存储:

{"author": "山鹰寂寞飞", "content": "那年那人那山第三十三章:炼狱化疗 传说中的化疗很快来到,秀芬和红军以为是什么工程浩大惊天动地的疗法,没成想也就是几瓶药水输进身体。    然而他们都小瞧了这几瓶药水的威力,刚挂上没一会,楚建国开始恶心,说胃里火烧火燎像有硫酸在腐蚀,不停的干呕着,后来实在憋持不住,让秀芬赶紧拿来垃圾桶,他侧倒在床沿翻江倒海的抽搐着身子,一阵又一阵吐得眼泪直流。    早上吃的东西全都吐了个干净,顺着嘴角又一佝偻一佝偻呕出黄疸水,偌大的一个壮汉,竟然像个孩子似的,吐的哭出了声音。    秀芬很害怕,去找值班医生,\n…\n \n\n 查看全文"}
{"author": "五少爷的刀", "content": "中午在食堂吃午饭的时候,刚好和厂长坐在一起,为了活跃气氛,我就讲了两个笑话。 厂长果然被我逗笑了,噗~的一声,把他刚扒进嘴里的饭全喷在我碗里了。。。 大家都放下了碗筷,扭头看我。 就在我在考虑是不是不要了的时间,厂长带的二哈跳起来把我的饭吃了!…… 谢天谢地啊,谢天谢地!!!……我站起来,朝着二哈,一躬到地。。。"}
{"author": "精灵不次饭~", "content": "穿了条新裙子,照镜子觉得特别好看。我脑子一抽就发视频给在玩游戏的老公,问他好看不,还跟他卖个萌做了个鬼脸。 现在我很想把他踹出家门!!这货不停的追问我“你直接喊我来看不就行了吗?”“我在家呢,你发视频干啥?”“你是不是发错人了?” “你本来打算发给谁的?”"}
.......

三、Scrapy糗事百科之抓取多个页面

修改qsbk_spider.py,分析"下一页"按钮的标签结构

# -*- coding: utf-8 -*-
import scrapy
from qsbk.items import QsbkItemclass QsbkSpiderSpider(scrapy.Spider):name = 'qsbk_spider'allowed_domains = ['qiushibaike.com']start_urls = ['https://www.qiushibaike.com/text/page/1/']base_domain = "https://www.qiushibaike.com"def parse(self, response):# SelectorListduanzidivs =  response.xpath("//div[@class='col1 old-style-col1']/div")# 遍历divfor duanzidiv in duanzidivs:# Selector-->author =  duanzidiv.xpath(".//a/h2/text()").get().strip()content = duanzidiv.xpath(".//div[@class='content']//text()").getall()content = " ".join(content).strip()item = QsbkItem(author=author,content=content)yield itemnext_url = response.xpath("//ul[@class='pagination']/li[last()]/a/@href").get()if not next_url:returnelse:yield scrapy.Request(self.base_domain+next_url,callback=self.parse)# 返回当前的请求

在setting文件中,找到下面的注释掉,可以调成一秒获取一次数据

# Configure a delay for requests for the same website (default: 0)
# See https://docs.scrapy.org/en/latest/topics/settings.html#download-delay
# See also autothrottle settings and docs
DOWNLOAD_DELAY = 1

Scrapy糗事百科爬虫实战代码分析相关推荐

  1. 网络爬虫---爬取糗事百科段子实战

    Python网络爬虫 1.知识要求 掌握python基础语法 熟悉urllib模块知识 熟悉get方法 会使用浏览器伪装技术 如果您对相关知识遗忘了,可以点上面的相关知识链接,熟悉一下. 2.爬取糗事 ...

  2. Python之爬取糗事百科段子实战

    "简说Python",选择"置顶/星标公众号" 福利干货,第一时间送达! 阅读本文大约6分钟,实战学习,老表建议你反复看,反复记,反复练. // 本文作者 王豪 ...

  3. Python爬虫 基于Beautiful Soup的糗事百科爬虫

    python爬虫 ---- 糗事百科爬虫 首先进入糗事百科官网首页 -> 糗事百科 本次爬虫的目标是翻页爬取糗事百科的信息,包括 标题, 链接, 作者名, 好笑数&评论数 之后右键检查, ...

  4. python实现数据爬取——糗事百科爬虫项目

    python实现数据爬取--糗事百科爬虫项目 # urllib.request 请求模块 import urllib.request # re 模块使 Python 语言拥有全部的正则表达式功能. i ...

  5. 糗事百科爬虫用户统计

    糗事百科爬虫用户统计 以前爬了糗事百科,一些数据还是挺有意思的: 工作 搬砖汉应该是调侃自己的,不过人数比较多的手艺汪,学生汪,家里蹲应该有一些共同点,那就是时间比较自由 故乡 基本上人口基数大的地方 ...

  6. [python3]糗事百科爬虫

    最近开始学习爬虫和机器学习,网上好多资料都是python2的,学习爬虫可见汪海大哥的专题[python爬虫入门教程] 这里将第八讲[糗事百科的网络爬虫(v0.3)源码及解析(简化更新) ]中的源码修正 ...

  7. Python爬虫实战(1):爬取糗事百科段子

    Python爬虫入门(1):综述 Python爬虫入门(2):爬虫基础了解 Python爬虫入门(3):Urllib库的基本使用 Python爬虫入门(4):Urllib库的高级用法 Python爬虫 ...

  8. 转 Python爬虫实战一之爬取糗事百科段子

    静觅 » Python爬虫实战一之爬取糗事百科段子 首先,糗事百科大家都听说过吧?糗友们发的搞笑的段子一抓一大把,这次我们尝试一下用爬虫把他们抓取下来. 友情提示 糗事百科在前一段时间进行了改版,导致 ...

  9. Python爬虫实战之爬取糗事百科段子

    Python爬虫实战之爬取糗事百科段子 完整代码地址:Python爬虫实战之爬取糗事百科段子 程序代码详解: Spider1-qiushibaike.py:爬取糗事百科的8小时最新页的段子.包含的信息 ...

最新文章

  1. 未来到底是什么样子?
  2. DL_WITH_PY系统学习(第2章)
  3. 配置tomcat的环境变量
  4. 快速求平方根,这个好牛逼
  5. Linux下软件安装和卸载
  6. ArrayAndString(数组和字符串)
  7. ASP.net的PDF打印(水晶报表)[摘]
  8. Python常用的几种数据结构-链表,数组,字典
  9. 计算机与临床医学的应用,论临床医学教育中计算机系统的应用.pdf
  10. 请问,非计算机专业,只为软考中级,哪一种最容易过?
  11. Landscape Photography: Autumn 风景摄影:秋天 Lynda课程中文字幕
  12. 如何利用SFTP在远程服务器中保障文件传输安全
  13. tmp在java中的意思_tmp是什么文件?tmp文件用什么打开?图文讲解
  14. 小米手机扩容教程_小米手机加运存和扩容(成功的DIY,过程已更新完)|创意DIY...
  15. SolidWorks+thonny esp32 电磁控制,程序算法搞起来了,我的结构-仿真-电磁-控制-算法的学习之路
  16. 7.27 web前端-淘宝首页设计3
  17. 苹果5壁纸_元气壁纸软件-元气壁纸安卓版下载v1.0.2
  18. 早起比晚睡更可怕...
  19. 杂学第十三篇:内网centos7安装软件或者其他动态库的依赖,本文章以安装openoffice为例(包含解决思路,可能适用其他系统)
  20. Apach POI 读取Excel图片

热门文章

  1. LeetCode 831. Masking Personal Information【字符串,正则表达式】中等
  2. 如何获得扬声器完美的单位冲激响应?
  3. 1072: 青蛙爬井 C语言
  4. 首款宇宙星际探索类卡牌游戏震撼上线
  5. swoole - 简介
  6. 单目视觉SLAM综述
  7. [UNR#5]诡异操作
  8. windows自带截图键(shift+ win + s)没有反应,一招教你快速解决!
  9. SpringBoot专栏 | SpringBoot2.x系列教程之花样配置--自定义Banner
  10. JavaScript时间日期