文章目录

  • 第十九章 crawlspider讲解
    • 1. 古诗文案例crawlspider
      • 1.1 需求
      • 1.2 处理
      • 1.3 解析
    • 2. 小程序社区案例
      • 2.1 创建项目
      • 2.2 项目配置
      • 2.3 解析详情页的数据
    • 3. 汽车之家案例(二进制数据爬取)
      • 3.1 创建项目
      • 3.2 项目配置
      • 3.3 定位图片
      • 3.4 配置settings
      • 3.5 创建开始文件
      • 3.6 打开管道
      • 3.7 在管道中操作
      • 3.8 图片存储路径代码解释
      • 3.9 解决报错问题
      • 3.10 翻页
    • 4. 其他方法爬取图片
      • 4.1 在items文件中创建两个字段
      • 4.2 导入items文件中的类并在爬虫文件中引用字段
      • 4.3 定义自己的管道
      • 4.4 完整代码
        • 4.4.1 items
        • 4.4.2 byd爬虫文件
        • 4.4.3 settings
      • 4.5 总结

第十九章 crawlspider讲解

今天我们来讲一下crawlspider,我们原则上先掌握最基础的,然后是高级一点的。我们将上一次的古诗文案例用crawspider来处理一下。

1. 古诗文案例crawlspider

创建项目文件:
终端输入:scrapy startproject gs20210217 回车
创建crawlspider爬虫项目,语句:
cd 到gs20210217文件夹中,终端输入:

scrapy genspider -t crawl 爬虫的名字 域名

然后输入创建项目语句,创建项目:

scrapy genspider -t crawl cgs https://www.gushiwen.cn/
Use "scrapy" to see available commandsD:\work\爬虫\Day21\my_code>scrapy startproject gs20210217
New Scrapy project 'gs20210217', using template directory 'd:\python38\lib\site-packages\scrapy\template
s\project', created in:D:\work\爬虫\Day21\my_code\gs20210217You can start your first spider with:cd gs20210217scrapy genspider example example.comD:\work\爬虫\Day21\my_code>cd gs20210217D:\work\爬虫\Day21\my_code\gs20210217>scrapy genspider -t crawl cgs https://www.gushiwen.cn/
Created spider 'cgs' using template 'crawl' in module:gs20210217.spiders.cgsD:\work\爬虫\Day21\my_code\gs20210217>

项目创建成功。

我们可以看到crawlspider比scrapyspider,继承的父类发生了变化,导入的模块多了一个。造类里面多了一个Rules:

class CgsSpider(CrawlSpider):name = 'cgs'allowed_domains = ['https://www.gushiwen.cn/']start_urls = ['http://https://www.gushiwen.cn//']rules = (Rule(LinkExtractor(allow=r'Items/'), callback='parse_item', follow=True),)

Rule定义提取url的规则,LinkExtractor是链接提取器。

  • allow=r’Items/'这个用来存放url (用到正则表达式)
  • callback='parse_item’是回调函数,处理请求结果。
  • follow=True继续跟进下一页
    下面我们通过案例来学习。

1.1 需求

仍然是爬取古诗文的详情。我们需要处理的事情一个是翻页,第二个是爬取译文。
我们需要列表页的url地址

https://www.gushiwen.cn/  # 第一页
https://www.gushiwen.cn/default_1.aspx # 第一页
https://www.gushiwen.cn/default_2.aspx # 第二页
https://www.gushiwen.cn/default_3.aspx # 第三页

另一个是详情页的url地址

https://so.gushiwen.cn/shiwenv_7c14409ca751.aspx  # 列表页第一页第一首诗的详情页
https://so.gushiwen.cn/shiwenv_0184c31a9e01.aspx # 列表页第一页第二首诗的详情页

我们的顺序是先爬第一页,第一页的第一首,第二首,完了,翻页。。。

1.2 处理

下面注意看代码中的注释:

import scrapy
from scrapy.linkextractors import LinkExtractor
from scrapy.spiders import CrawlSpider, Ruleclass CgsSpider(CrawlSpider):name = 'cgs'allowed_domains = ['https://www.gushiwen.cn/']start_urls = ['http://https://www.gushiwen.cn//']rules = (# 负责列表页Rule(LinkExtractor(allow=r'https://www.gushiwen.cn/default_1.aspx'), follow=True),# 负责详情页Rule(LinkExtractor(allow=r'https://so.gushiwen.cn/shiwenv_7c14409ca751.aspx'), callback='parse_item', ))  # 详情页不需要翻页,所以去掉follow=True# 列表页不需要数据,只需要翻页,所以不需要回调函数,去掉callback='parse_item'def parse_item(self, response):item = {}#item['domain_id'] = response.xpath('//input[@id="sid"]/@value').get()#item['name'] = response.xpath('//div[@id="name"]').get()#item['description'] = response.xpath('//div[@id="description"]').get()return item

下面我们需要把url里面的跟随翻页变化的字符用正则表达式来匹配一下:

 # 负责列表页 正则匹配1-10=>\d+Rule(LinkExtractor(allow=r'https://www.gushiwen.cn/default_\d+.aspx'), follow=True),# 负责详情页 正则匹配7c14409ca751 =>\w+Rule(LinkExtractor(allow=r'https://so.gushiwen.cn/shiwenv_\w+.aspx'), callback='parse_item', )

\d可以匹配0-9的数字,+表示至少匹配一次。\W可以匹配大小写字母和数字,+也是至少匹配一次。关于正则表达式的只是请参考我的博客[爬虫(05)正则表达式]。(https://blog.csdn.net/m0_46738467/article/details/111587355)
这样我们就将列表页和详情页的url用正则表达式匹配完成。crawlspider只适合简单一些的url,如果url构成比较复杂,就用一般的爬虫方式就可以了。

1.3 解析

我们只需要详情页的译文,我们把第19次博客案例解析译文的代码复制过来就可以了。

    def parse_item(self, response):item = {}#item['domain_id'] = response.xpath('//input[@id="sid"]/@value').get()#item['name'] = response.xpath('//div[@id="name"]').get()#item['description'] = response.xpath('//div[@id="description"]').get()shang = response.xpath('//div[@class="contyishang"]/p/text()').extract()content_shang = ''.join(shang).strip()  # 处理空格及换行符item['detail_content'] = content_shang  # 加入itemsprint(item)return item

去settings里面设置一下:

LOG_LEVEL = 'WARNING'
ROBOTSTXT_OBEY = False
DEFAULT_REQUEST_HEADERS = {'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.104 Safari/537.36','Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8','Accept-Language': 'en',
}

然后我们创建一个start文件:

from scrapy import cmdline
cmdline.execute('scrapy crawl cgs'.split())

我们运行一下:

{'detail_content': '译文富家的子弟不会饿死,清寒的读书人大多贻误自身。韦大人你可以静静地细听,我把自己的往事向你直陈。我在少年时候,早就充当参观王都的来宾。先后读熟万卷书籍,写起文章,下笔敏捷好像有神。我的辞赋能与扬雄匹敌,我的诗篇可跟曹植相近。李邕寻求机会要和我见面,王翰愿意与我结为近邻。自以为是一个超异突出的人,一定很快地身居要津。辅助君王使他在尧舜之上,要使社会风尚变得敦厚朴淳。平生的抱负全部落空,忧愁歌吟,决不是想优游退隐。骑驴行走了十三年,寄食长安度过不少的新春。早上\n\u3000\u3000在杜甫困守长安十年时期所写下的求人援引的诗篇中,要数这一首是最好的了。这类社交性的诗,带有明显的急功求利的企图。常人写来,不是曲意讨好对方,就是有意贬低自己,容易露出阿谀奉承、俯首乞怜的寒酸相。杜甫在这首诗中却能做到不卑不亢,直抒胸臆,吐出长期郁积下来的对封建统治者压制人材的悲愤不平。这是他超出常人之处。\u3000\u3000诗人主要运用了对比和顿挫曲折的表现手法,将胸中郁结的情思,抒写得如泣如诉,真切动人。这首诗应该说是体现杜诗“沉郁顿挫”风格的最早的一篇。\u3000\u3000诗中对比有两种情况,一是以他人和自己对比;一是以自己的今昔对比。先说以他人和自己对比。开端的“纨袴不饿死\n\u3000\u3000此诗作于公元748年(唐玄宗天宝七载),时37岁,居长安。公元747年(天宝六载),唐玄宗下诏天下有一技之长的人入京赴试,命尚书省试,对所有应试之人统统不予录取。杜甫这时应试落第,困守长安,心情落寞,想离京出游,于是就写了这首诗向韦济告别。'}
{'detail_content': '译文你挥舞彩袖手捧酒杯殷勤劝酒,回想当年心甘情愿醉倒于颜红。舞姿曼妙,直舞到挂在杨柳树梢照到楼心的一轮明月低沉下去;歌女清歌婉转,直唱到扇底儿风消歇。自从那次离别后,我总是怀念那美好的相逢,多少回梦里与你共同欢聚。今夜里我举起银灯把你细看,唯恐这次相逢又是在梦中。注释鹧鸪天:词牌名,又名“思佳客”,五十五字。 此词黄升《花庵词选》题作《佳会》。彩袖:代指穿彩衣的歌女。玉钟:古时指珍贵的酒杯,是对酒杯的美称。拚(pàn)却:甘愿,不顾惜。却:语气助词。“舞低”二句:歌女舞姿曼妙,直舞到挂在\n\u3000\u3000言为心声,有至情之人,才能有至情之文。一首《鹧鸪天》,写悲感,写欢情,都是那样真挚深沉,撼人肺\u3000\u3000腑,具有强烈的感情色彩。虽然这首词的题材比较窄,不外乎伤离怨别,感悟怀旧,遣情遗恨之作,并没有超出晚唐五代词人的题材范围。小晏写情之作的动人处,在于它的委婉细腻,情深意浓而又风流妩媚,清新俊逸。白居易曰:“感人心者,莫先乎情。”古往今来,脍炙人口的诗词,大抵不仅有情,而且情真。所谓“真字是词骨。情真、景真,所作必佳,且易脱稿。”\u3000\u3000彩袖殷勤捧玉钟,当年拚却醉颜红。舞低杨柳楼新月,歌尽桃花扇低风。\u3000\u3000一个是殷勤地劝酒,一个是拼命地喝,为\n\u3000\u3000此词表现的是一对恋人的“爱情三部曲”:初盟,别离,重逢。全词不过五十几个字,而能造成两种境界,互相补充配合,或实或虚,既有彩色的绚烂,又有声音的谐美,足见作者词艺之高妙。\u3000\u3000“彩袖殷勤”二句,着笔于对方,落墨于自身,既展现了二人初识时的特定情境,也披露了二人一见倾心、愿托终身之际的曲折心态。“彩袖”,说明对方并非与自已门第相配的大家闺秀,而不过是侑酒于华宴的歌女。但此时伊人殷勤捧杯劝饮,却不仅仅是履行侑酒之责,而欲藉此暗通情愫。而心有屡犀的作者又何尝不谙其意?为了报答她于已独钟的深情,他开怀畅饮,不惜一醉。这就写出了感情的双向交流。\u3000\u3000“舞低杨柳”\n\u3000\u3000在仁宗至和二年(公元1055年)就已亡故,则因反对新法,逐渐失势,后于熙宁五年(1072)病故,这使失去了政治上的依靠,生活景况日趋恶化。晏几道采用忆昔思今对比手法写下了许多追溯当年回忆的词作,《鹧鸪天·彩袖殷勤捧玉钟》便是这其中的佼佼之作。\u3000\u3000这首词是晏几道与几个相熟的女子久别重逢之作。这个女子可能是晏几道自撰《小山词序》中所提到的他的朋友沈廉叔、陈君龙家歌女莲、鸿、蘋、云诸人中的一个。晏几道经常在这两位朋友家饮酒听歌,与这个女子是很熟的而且有相当爱惜之情的,离别之后,时常思念,哪知道现在忽然不期而重遇,又惊又喜,所以作了这首词。\u3000\u3000上半阕写当年相聚时欢乐之况,下半阕写今日重逢的惊喜之情。\u3000\u3000“彩袖殷勤捧玉钟,当年拚却醉颜红。舞低杨柳楼心月,歌尽桃花扇底风。”这首词上半阕是说,忆当年,你手捧玉鍾把酒敬,衣着华丽人多情;我举杯痛饮拼一醉,醉意熏熏脸通红。纵情跳舞,直到楼顶月挨着树梢向下行;'}... ... 后面的省略

我书了一下,一共一百个。十页的内容全部爬取了。

2. 小程序社区案例

网址:http://www.wxapp-union.com/portal.php?mod=list&catid=2&page=1

我们爬取标题,作者,时间。

那这个项目是否满足我们的crawlscrapy的条件呢?
我们先看看url

http://www.wxapp-union.com/portal.php?mod=list&catid=2&page=1  # 第一页
http://www.wxapp-union.com/portal.php?mod=list&catid=2&page=2 # 第二页http://www.wxapp-union.com/article-6908-1.html # 第一页的第一个详情页
http://www.wxapp-union.com/article-6907-1.html # 第一页的第二个详情页
http://www.wxapp-union.com/article-6906-1.html # 第一页的第三个详情页

我们看到,url很简单,而且有规律性。

2.1 创建项目

先创建项目:
打开终端Terminal,回到根文件夹:

创建项目:

scrapy startproject sp


创建成功。cd到sp文件夹

D:\work\爬虫\Day21\my_code\sp>

创建crawlscrapy爬虫项目:

scrapy genspider -t crawl wxapp 'wxapp-union.com'

2.2 项目配置

下面我们进行项目配置,列表页和详情页配置:

  • 列表页 去掉callback=‘parse_item’,将url添加进去
  • 详情页 去掉,follow=True,将详情页的url添加进去
  • 正则匹配随页码变化的字符
 rules = (# 列表页Rule(LinkExtractor(allow=r'http://www.wxapp-union.com/portal.php\?mod=list&catid=2&page=\d+'),  follow=True),# 详情页Rule(LinkExtractor(allow=r'http://www.wxapp-union.com/article-\d+-1.html'), callback='parse_item'),)

特别注意,在列表页的url里面有一个问好,会被误认为正则匹配,一定要用反斜杠转义。

2.3 解析详情页的数据

item['标题:'] = response.xpath('//h1[@class="ph"]/text()').extract_first() # 标题
item['作者:'] = response.xpath('//p[@class="authors"]/a/text()').extract_first() # 作者
item['时间:'] = response.xpath('//p[@class="authors"]/span/text()').extract_first() # 时间
print(item)

下面我们配置一下settings

LOG_LEVEL = 'WARNING'
ROBOTSTXT_OBEY = False
DEFAULT_REQUEST_HEADERS = {'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.104 Safari/537.36','Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8','Accept-Language': 'en',
}

创建start文件

from scrapy import cmdline
cmdline.execute('scrapy crawl wxapp'.split())

运行一下:

{'标题:': '微信小程序-bindtap等事件传参 ', '作者:': 'Rolan', '时间:': '2021-2-9 23:48'}
{'标题:': '微信小程序从登录到首页流程梳理 ', '作者:': 'Rolan', '时间:': '2021-2-8 10:12'}
{'标题:': '微信小程序---自动化测试 ', '作者:': 'Rolan', '时间:': '2021-2-7 09:30'}
{'标题:': '我用两周开发了一个图片类应用微信小程序(一) ', '作者:': 'Rolan', '时间:': '2021-2-8 10:02'}
{'标题:': '微信小程序生命周期和页面的生命周期 ', '作者:': 'Rolan', '时间:': '2021-2-8 10:14'}
{'标题:': '【微信小程序】自定义导航栏 ', '作者:': 'Rolan', '时间:': '2021-2-7 10:33'}
{'标题:': '微信小程序支付(服务商模式)解决 ', '作者:': 'Rolan', '时间:': '2021-2-7 09:44'}
{'标题:': '极速入门微信小程序 之 生命周期篇(2-页面) ', '作者:': 'Rolan', '时间:': '2021-2-8 09:39'}
{'标题:': '聊一聊小程序如何换肤 ', '作者:': 'Rolan', '时间:': '2021-2-8 09:59'}
{'标题:': '微信限量红包封面免费送,人人都能领! ', '作者:': 'Rolan', '时间:': '2021-2-8 18:34'}
{'标题:': '小程序搜索功能:云开发搜索和小程序云开发模糊搜索,同时搜索多个字段 ... ', '作者:': 'Rolan', '时间:': '2021-2-9 09:19'}
{'标题:': '微信小程序开发流程与核心概念 ', '作者:': 'Rolan', '时间:': '2021-2-9 18:31'}
{'标题:': '微信小程序swiper实现 句子控app首页滑动卡片 ', '作者:': 'Rolan', '时间:': '2021-2-9 23:38'}

拿到了数据,不过只拿到13个数据,好像没有翻页。这是因为start_url=‘http://wxapp-union.com/’不是起始url=‘http://www.wxapp-union.com/portal.php?mod=list&catid=2&page=1’。我们把它换成后面的就可以了。

name = 'wxapp'allowed_domains = ['wxapp-union.com']start_urls = ['http://www.wxapp-union.com/portal.php?mod=list&catid=2&page=1']

再运行一下

{'标题:': '微信小程序开发流程与核心概念 ', '作者:': 'Rolan', '时间:': '2021-2-9 18:31'}
{'标题:': '从微信小程序到鸿蒙js开发【05】——tabs组件&每日新闻 ', '作者:': 'Rolan', '时间:': '2021-2-7 09:16'}
{'标题:': '从零开始的微信小程序入门教程(二),初识WXML与WXSS ', '作者:': 'Rolan', '时间:': '2021-2-5 09:34'}
{'标题:': '微信小程序支付(服务商模式)解决 ', '作者:': 'Rolan', '时间:': '2021-2-7 09:44'}
{'标题:': '小程序省市区选择器,对接公司的地址数据 ', '作者:': 'Rolan', '时间:': '2021-2-7 09:27'}
{'标题:': '微信小程序---自动化测试 ', '作者:': 'Rolan', '时间:': '2021-2-7 09:30'}
{'标题:': '【微信小程序】自定义导航栏 ', '作者:': 'Rolan', '时间:': '2021-2-7 10:33'}
... ...
{'标题:': '携程小程序初体验 ', '作者:': 'Rolan', '时间:': '2018-6-12 00:12'}
{'标题:': '【微信小程序】编译 .wxss 文件异常解决 ', '作者:': 'Rolan', '时间:': '2018-6-29 00:21'}
{'标题:': '微信小程序瀑布流最好最简单的解决方案 ', '作者:': 'Rolan', '时间:': '2018-6-11 00:45'}
{'标题:': '利用css transition属性实现一个带动画显隐的微信小程序部件 ', '作者:': 'Rolan', '时间:': '2018-6-12 00:23'}
{'标题:': '小程序js文件改变参数并在视图上及时更新 ', '作者:': 'Rolan', '时间:': '2018-6-12 00:28'}
{'标题:': '微信小程序利用canvas生成海报分享图片 ', '作者:': 'Rolan', '时间:': '2018-6-29 00:12'}
{'标题:': '微信小程序专题之setData ', '作者:': 'Rolan', '时间:': '2018-6-29 00:26'}

数据太多了,就省略了。

3. 汽车之家案例(二进制数据爬取)

下面我们练习爬取一下图片,我们以汽车之家的图片为例。这是比亚迪F3的图片地址,这个图片比较多,共356张图片。
网址:https://car.autohome.com.cn/photolist/series/407/p1/

找url规律:

https://car.autohome.com.cn/photolist/series/407/p1/  # 第一页
https://car.autohome.com.cn/photolist/series/407/p2/  # 第二页
https://car.autohome.com.cn/photolist/series/407/p3/  # 第三页
https://car.autohome.com.cn/photolist/series/407/p4/  # 第四页

我们看到规律很明显。
再看看图片的位置,右键图片,检查:

我们看到图片在li标签里的img标签里,src的值。

3.1 创建项目

创建项目的步骤我们已经很熟悉了:

  • 创建scrapy项目
  • 创建spider项目
    我们创建一个picture的文件夹作为根目录文件夹。
    我们cd到这个文件夹中,创建scrapy项目:
D:\work\爬虫\Day21\my_code\picture>scrapy startproject carhome

回车

D:\work\爬虫\Day21\my_code\picture>scrapy startproject carhome
New Scrapy project 'carfamily', using template directory 'd:\python38\lib\site-packages\scrapy\templates
\project', created in:D:\work\爬虫\Day21\my_code\picture\carhomeYou can start your first spider with:cd carhomescrapy genspider example example.comD:\work\爬虫\Day21\my_code\picture>

先cd到carhome文件夹,然后创建spider项目:

scrapy genspider byd car.autohome.com.cn

回车

D:\work\爬虫\Day21\my_code\picture>scrapy startproject carhome
New Scrapy project 'carhome', using template directory 'd:\python38\lib\site-packages\scrapy\templates\p
roject', created in:D:\work\爬虫\Day21\my_code\picture\carhomeYou can start your first spider with:cd carhomescrapy genspider example example.comD:\work\爬虫\Day21\my_code\picture>cd carhomeD:\work\爬虫\Day21\my_code\picture\carhome>scrapy genspider byd car.autohome.com.cn
Created spider 'byd' using template 'basic' in module:carhome.spiders.bydD:\work\爬虫\Day21\my_code\picture\carhome>

3.2 项目配置

我们先把start_url改变一下:

import scrapyclass BydSpider(scrapy.Spider):name = 'byd'allowed_domains = ['car.autohome.com.cn']start_urls = ['https://car.autohome.com.cn/photolist/series/407/p1/']def parse(self, response):pass

3.3 定位图片

找图片的位置,用xpath定位:

    def parse(self, response):ul = response.xpath('//ul[@id="imgList"]/li').extract() # 该页所有的图片for li in ul:pass

这里我们不仅要拿到图片的地址,还要给图片命名,为了避免重复,而我们可以截取图片的部分url作为图片名。

    def parse(self, response):ul = response.xpath('//ul[@id="imgList"]/li').extract() # 该页所有的图片for li in ul:item = {} # 定义字典存储数据item['src'] = li.xpath('./a/img/@src').extract_first() # 图片urlprint(item)

3.4 配置settings

配置一下settings:

LOG_LEVEL = 'WARNING'
ROBOTSTXT_OBEY = False
DEFAULT_REQUEST_HEADERS = {'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.104 Safari/537.36','Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8','Accept-Language': 'en',
}

3.5 创建开始文件

创建start文件

from scrapy import cmdline
cmdline.execute('scrapy crawl byd'.split())


我们先运行一下,看看能否取出数据:

{'src': '//car3.autoimg.cn/cardfs/product/g24/M01/9A/87/240x180_0_q95_c42_autohomecar__ChwFjl7Ph8yAW5-NAAjdsZ5xYqw557.jpg'}
{'src': '//car3.autoimg.cn/cardfs/product/g2/M0B/7E/8B/240x180_0_q95_c42_autohomecar__ChwFql7Ph8qAS2o5AAkmafu7Hu8233.jpg'}
{'src': '//car3.autoimg.cn/cardfs/product/g2/M02/94/05/240x180_0_q95_c42_autohomecar__ChsEml7Ph8mAcGLTAAkqDMhAt7A709.jpg'}
{'src': '//car2.autoimg.cn/cardfs/product/g2/M01/7E/8B/240x180_0_q95_c42_autohomecar__ChwFql7Ph8eAaabjAAj6QWpEae4702.jpg'}
后面的省略

我们随便复制一个到浏览器看看:
浏览器自动补全了网址,但我们在代码里要拼接完整:

 item['src'] = 'https:'+li.xpath('./a/img/@src').extract_first() # 图片url

3.6 打开管道

下面我们打开管道,

ITEM_PIPELINES = {'carhome.pipelines.CarhomePipeline': 300,
}

将上面的代码激活,然后把数据yield给管道

    def parse(self, response):ul = response.xpath('//ul[@id="imgList"]/li') # 该页所有的图片for li in ul:item = {} # 定义字典存储数据item['src'] = 'https:'+li.xpath('./a/img/@src').extract_first() # 图片urlyield item

3.7 在管道中操作

在pipelines里面命名图片,我们截取src的一部分命名图片:

{'src': 'https://car2.autoimg.cn/cardfs/product/g2/M01/7E/8B/240x180_0_q95_c42_autohomecar__ChwFql7Ph8eAaabjAAj6QWpEae4702.jpg'}# 我们可以截取后面这部分ChwFql7Ph8eAaabjAAj6QWpEae4702.jpg

下面是图片名的代码:

        img_name = item['src'].split('__')[-1]

这个代码的意思是:用双下划线分割src,得到的两个元素返回成的列表中,取倒数第一个元素。
我们创建一个文件夹来存储图片。

下面我们导入一个模块urllib来处理图片存储的问题:

    def process_item(self, item, spider):# 获取图片的urlsrc = item['src']# 切割src的一部分作为图片的名字img_name = item['src'].split('__')[-1]# D:\work\爬虫\Day21\my_code\picture\carhome\carhome\imagesfile_path = os.path.join(os.path.dirname(__file__),'images')request.urlretrieve(src,file_path+'/'+img_name)

3.8 图片存储路径代码解释

其中 file_path = os.path.join(os.path.dirname(file),‘images’)这行代码的意思我解释一下。
我们在my_code文件夹中创建一个新的demo文件来演示:

我们看到打印的结果是合成的一个路径。下面的代码看注释和执行结果,你可以明白的。

import os
# os.path.join()把目录和文件名合成一个路径
print(os.path.join('文件夹','新文件'))
# os.path.dirname() 返回文件路径,就是往前退一步
# 打印当前文件的路径的方法:
print(__file__)
# 打印结果:D:/work/爬虫/Day21/my_code/demo.py
# 返回当前文件路径的方法
print(os.path.dirname(__file__))
# 打印结果:D:/work/爬虫/Day21/my_code


那么我们刚才的代码就是给图片创建一个存储路径:

 file_path = os.path.join(os.path.dirname(__file__),'images')

就是当前文件往前退一步就是images文件夹所在的文件夹,然后再与’images’合成一个路径。
完整的存储代码是这样子的:

from urllib import request
import os
class CarhomePipeline:def process_item(self, item, spider):# 获取图片的urlsrc = item['src']# 切割src的一部分作为图片的名字img_name = item['src'].split('__')[-1]# D:\work\爬虫\Day21\my_code\picture\carhome\carhome\imagesfile_path = os.path.join(os.path.dirname(__file__),'images')request.urlretrieve(src,file_path+'/'+img_name)return item

3.9 解决报错问题

运行的时候发现有gif格式的图片不能爬取,所以加入try语句解决问题:

   def process_item(self, item, spider):# 获取图片的urlsrc = item['src']# 切割src的一部分作为图片的名字img_name = item['src'].split('__')[-1]# D:\work\爬虫\Day21\my_code\picture\carhome\carhome\imagesfile_path = os.path.join(os.path.dirname(__file__),'images')try:request.urlretrieve(src,file_path+'/'+img_name)print(img_name)except OSError:print('gif类型,跳过')passreturn item

这次运行爬取了30张图片,说明值爬取了一页。

ChwFjl7Ph8yAW5-NAAjdsZ5xYqw557.jpg
ChwFql7Ph8qAS2o5AAkmafu7Hu8233.jpg
ChsEml7Ph8mAcGLTAAkqDMhAt7A709.jpg
ChwFql7Ph8eAaabjAAj6QWpEae4702.jpg......中间的省略......
ChsEe15WWuiAY8CrAATAcuXSwT4702.jpg
ChwFlV7PiJ2AV7ikAAgHgKLCjKM407.jpg
ChwFjl7PiJ2ADJMmAAf2h7UtNg0272.jpg
ChwFjl7PiJyAA531AAiaVL_FGsM021.jpg
gif类型,跳过
gif类型,跳过
gif类型,跳过
gif类型,跳过
gif类型,跳过

3.10 翻页

下面在byd文件里加上翻页处理:

import scrapyclass BydSpider(scrapy.Spider):name = 'byd'allowed_domains = ['car.autohome.com.cn']first_url = 'https://car.autohome.com.cn/photolist/series/407/p{}/'start_urls = [first_url.format(1)]def parse(self, response):ul = response.xpath('//ul[@id="imgList"]/li') # 该页所有的图片for li in ul:item = {} # 定义字典存储数据item['src'] = 'https:'+li.xpath('./a/img/@src').extract_first() # 图片urlyield item# 处理翻页for i in range(2,7):next_url = self.first_url.format(i)yield scrapy.Request(next_url)pass

运行结果

一共爬取了156张图片。

4. 其他方法爬取图片

除了上述一般的爬取方式,也有别的爬取方式,比如选择使用scrapy内置的下载文件的方法:
下载文件的 Files Pipeline
使用Files Pipeline下载文件,按照以下步骤完成:

  • 定义好一个Item,然后在这个item中定义两个属性,分别为file_urls以及files。files_urls是用来存储需要下载的文件的url链接,需要给一个列表
  • 当文件下载完成后,会把文件下载的相关信息存储到item的files属性中。如下载路径、下载的url和文件校验码等
  • 在配置文件settings.py中配置FILES_STORE,这个配置用来设置文件下载路径
  • 启动pipeline:在ITEM_PIPELINES中设置scrapy.piplines.files.FilesPipeline:1
    下载图片的 Images Pipeline
    使用images pipeline下载文件步骤:
  • 定义好一个Item,然后在这个item中定义两个属性,分别为image_urls以及images。image_urls是用来存储需要下载的文件的url链接,需要给一个列表
  • 当文件下载完成后,会把文件下载的相关信息存储到item的images属性中。如下载路径、下载的url和图片校验码等
  • 在配置文件settings.py中配置IMAGES_STORE,这个配置用来设置文件下载路径
  • 启动pipeline:在ITEM_PIPELINES中设置scrapy.pipelines.images.ImagesPipeline:1

下面我们操作一下下载图片的pipeline:

4.1 在items文件中创建两个字段

打开items文件,创建两个字段:

import scrapyclass CarhomeItem(scrapy.Item):# define the fields for your item here like:# name = scrapy.Field()image_urls = scrapy.Field() # 存放urlimages = scrapy.Field() # 存放图片pass

4.2 导入items文件中的类并在爬虫文件中引用字段

我们把该文件所在文件夹的上一级文件夹carhome定义为根目录,然后在byd项目文件中导入CarhomeItem类并实例化,把byd文件里面的url键名也改了:

import scrapyfrom carhome.items import CarhomeItem # 导入items文件中的CarhomeItem
class BydSpider(scrapy.Spider):name = 'byd'allowed_domains = ['car.autohome.com.cn']first_url = 'https://car.autohome.com.cn/photolist/series/407/p{}/'start_urls = [first_url.format(1)]def parse(self, response):ul = response.xpath('//ul[@id="imgList"]/li') # 该页所有的图片for li in ul:item = CarhomeItem() # 实例化类item['image_urls'] = ['https:'+li.xpath('./a/img/@src').extract_first()] # 图片url# 上面的结果一定要以列表的形式返回yield item# 处理翻页for i in range(2,7):next_url = self.first_url.format(i)yield scrapy.Request(next_url)pass

4.3 定义自己的管道

然后打开settings配置它自己的一个pipeline

ITEM_PIPELINES = {# 'carhome.pipelines.CarhomePipeline': 300,'scrapy.pipelines.images.ImagesPipeline':1,
}

注意:在byd项目文件中,最后返回的是一个列表。

在settings里添加存储路径:

这个路径是从pipelines文件里复制过来的,但是一定要把路径的名字改成IMAGES_STORE
下面我们运行一下:

    IMAGES_STORE = os.path.join(os.path.dirname(__file__),'images')
NameError: name 'os' is not defined

报错了,忘记在settings文件里引用os模块,下面引用一下:

import os
IMAGES_STORE = os.path.join(os.path.dirname(__file__),'images')
# 文件存储路径,这里的IMAGES_STORE名字不能改变

再次运行,没有报错

查看有没有下载下来:

我们打开看看吧

我们看到爬取结果是一样的。所有的存储程序全部内部处理了。包括装图片的文件夹名还有图片名都是内部处理的。

4.4 完整代码

下面把几个文件的完整代码罗列出来。

4.4.1 items

# Define here the models for your scraped items
#
# See documentation in:
# https://docs.scrapy.org/en/latest/topics/items.htmlimport scrapyclass CarhomeItem(scrapy.Item):# define the fields for your item here like:# name = scrapy.Field()image_urls = scrapy.Field() # 存放urlimages = scrapy.Field() # 存放图片pass

4.4.2 byd爬虫文件

import scrapyfrom carhome.items import CarhomeItem
class BydSpider(scrapy.Spider):name = 'byd'allowed_domains = ['car.autohome.com.cn']first_url = 'https://car.autohome.com.cn/photolist/series/407/p{}/'start_urls = [first_url.format(1)]def parse(self, response):ul = response.xpath('//ul[@id="imgList"]/li') # 该页所有的图片for li in ul:# item = {} # 定义字典存储数据item = CarhomeItem() # 实例化类item['image_urls'] = ['https:'+li.xpath('./a/img/@src').extract_first()] # 图片url# 注意:在使用自定义管道的时候,这里返回的是一个列表yield item# 处理翻页for i in range(2,7):next_url = self.first_url.format(i)yield scrapy.Request(next_url)pass

4.4.3 settings

BOT_NAME = 'carhome'SPIDER_MODULES = ['carhome.spiders']
NEWSPIDER_MODULE = 'carhome.spiders'
LOG_LEVEL = 'WARNING'# Obey robots.txt rules
ROBOTSTXT_OBEY = False# Override the default request headers:
DEFAULT_REQUEST_HEADERS = {'user-agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/88.0.4324.104 Safari/537.36','Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8','Accept-Language': 'en',
}ITEM_PIPELINES = {# 'carhome.pipelines.CarhomePipeline': 300,'scrapy.pipelines.images.ImagesPipeline':1,
}import os
IMAGES_STORE = os.path.join(os.path.dirname(__file__),'images')
# 文件存储路径,这里的IMAGES_STORE名字不能改变

4.5 总结

总结一下使用images pipeline下载文件步骤:

  • items文件中定义两个字段:
image_urls = scrapy.Field() # 存放url
images = scrapy.Field() # 存放图片

并在爬虫文件中引入

  • settings文件中做了配置
    指定了路径
import os
IMAGES_STORE = os.path.join(os.path.dirname(__file__),'images')
# 文件存储路径,这里的IMAGES_STORE名字不能改变

不用自带的管道,开启自己的管道

ITEM_PIPELINES = {# 'carhome.pipelines.CarhomePipeline': 300,'scrapy.pipelines.images.ImagesPipeline':1,
}
  • 注意爬虫文件中解析的数据返回的是列表
item['image_urls'] = ['https:'+li.xpath('./a/img/@src').extract_first()] # 图片url
# 注意:在使用自定义管道的时候,这里返回的是一个列表

主要用一般方法下载,特殊情况用这种方法下载。

爬虫(21)crawlspider讲解古诗文案例补充+小程序社区案例+汽车之家案例+scrapy内置的下载文件的方法相关推荐

  1. 视频教程-微信小程序开发【初级篇 / 附案例】-微信开发

    微信小程序开发[初级篇 / 附案例] 北风网讲师!瓢城Web俱乐部创始人,教学总监! 李炎恢 ¥129.00 立即订阅 扫码下载「CSDN程序员学院APP」,1000+技术好课免费看 APP订阅课程, ...

  2. 爬虫框架Scrapy(10)下载文件与图片

    文章目录 下载文件与图片 (一)FilesPipeline 和 ImagesPipeline 1. FilesPipeline 使用说明 2. ImagesPipeline 使用说明 (二)项目实例: ...

  3. android小程序案例_小程序案例赏析:高质量的小程序怎么做

    很多新手想做小程序,但却不知道好的小程序应该做成什么样子.下面就跟大家分享几个做得比较好的微信小程序案例,你可以从这些案例中学习一下,然后再做自己的小程序. 1.商城小程序案例 商城小程序如今是比较常 ...

  4. 只要功夫深,菜鸟也能写出细节满满的古茗点单小程序

    前言 写在项目前的话: 临近期末了,各学科纷纷结课,随之而来的是各个课设的纷至沓来.俗话说得好,大学生的生活前五个月是温水泡脚,那么最后一个月的就是将前五个月泡脚的水喝下去.作为一个平日里摸鱼摸惯的摸 ...

  5. Python爬虫系列之爬取某优选微信小程序全国店铺商品数据

    Python爬虫系列之爬取某优选微信小程序全国商品数据 小程序爬虫接单.app爬虫接单.网页爬虫接单.接口定制.网站开发.小程序开发 > 点击这里联系我们 < 微信请扫描下方二维码 代码仅 ...

  6. 微信小程序将html转为wxml开发案例

    微信小程序开发虽说是比较偏向前端开发,但是它们的语法结构又不太一样.例如,wxml跟html就有本质的不同,就拿a标签来说吧,wxml是不支持a标签的,还有就是wxml不兼容html,下面小编就针对这 ...

  7. Python3爬虫——用BeautifulSoup解析古诗文网

    我们之前已经用Xpath分析过了古诗文网,但还是感觉有点麻烦,所以今天来讲BeautifulSoup库,它可以很方便的帮我们抓取网页的数据,同样也支持lxml解析器,下面我们来详细介绍: 安装Beau ...

  8. 爬取汽车之家图片 - scrapy - crawlspider - python爬虫案例

    爬取汽车之家图片 需求:爬取汽车之家某一个汽车的图片 ​ 一. 普通scrapy 第一步 页面分析 目标url: https://car.autohome.com.cn/photolist/serie ...

  9. python爬取微信小程序源代码_【实战】CrawlSpider实现微信小程序社区爬虫

    概述: 在人工智能来临的今天,数据显得格外重要.在互联网的浩瀚大海洋中,隐藏着无穷的数据和信息.因此学习网络爬虫是在今天立足的一项必备技能.本路线专门针对想要从事Python网络爬虫的同学而准备的,并 ...

最新文章

  1. Creating Lists
  2. Python中获取异常(try Exception)信息
  3. python接口自动化(二十四)--unittest断言——中(详解)
  4. JSP简单练习-定时刷新页面
  5. Java享元模式之字符串享元
  6. 使用jquery当页面打开时,将修改样式的点击事件绑定到Dom
  7. ROS( C++ )订阅 robot 的 path 话题
  8. xampp 配置虚拟主机
  9. 套用带标题行的表格样式_比格式刷好用10倍,原来Excel表格还有这么神奇的功能!...
  10. 使用Onedrive
  11. 对Java中字符串的进一步理解
  12. 计算机网络AD名词解释,计算机网络名词解释 AD是什么意思?
  13. sw2014计算机配置,SolidWorks 2014电脑配置要求
  14. CocosCreator之绳索摆动效果
  15. 联想服务器系统备份,操作演示:恢复预装系统前的数据备份方法
  16. dm8148 开发只boot启动参数vram=128简介
  17. Windows WSL2 安装Nvidia-Docker GPU 驱动Paddlepaddle
  18. 【CSDN软件工程师能力认证学习精选】不用框架,python实现卷积神经网络
  19. linux 时间 find,linux find 时间time
  20. 低成本实现三联屏拼接

热门文章

  1. 网易云音乐中你见过最扎心的热评是什么
  2. Retrofit2.0介绍使用封装
  3. PTA 背包问题凑零钱
  4. Hey~程序员,你的桌面风格该换了
  5. 中国移动,电信,联通,铁通,网通的区别与联系
  6. 游戏中掉落效果的实现
  7. AppNode面板安装搭建教程
  8. 男同胞要一定要看——酒桌上用来劝酒的话
  9. win7下安装ArcGIS9.3步骤与破解过程
  10. 정부와동포 사고 전화해야