爬虫(21)crawlspider讲解古诗文案例补充+小程序社区案例+汽车之家案例+scrapy内置的下载文件的方法
文章目录
- 第十九章 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内置的下载文件的方法相关推荐
- 视频教程-微信小程序开发【初级篇 / 附案例】-微信开发
微信小程序开发[初级篇 / 附案例] 北风网讲师!瓢城Web俱乐部创始人,教学总监! 李炎恢 ¥129.00 立即订阅 扫码下载「CSDN程序员学院APP」,1000+技术好课免费看 APP订阅课程, ...
- 爬虫框架Scrapy(10)下载文件与图片
文章目录 下载文件与图片 (一)FilesPipeline 和 ImagesPipeline 1. FilesPipeline 使用说明 2. ImagesPipeline 使用说明 (二)项目实例: ...
- android小程序案例_小程序案例赏析:高质量的小程序怎么做
很多新手想做小程序,但却不知道好的小程序应该做成什么样子.下面就跟大家分享几个做得比较好的微信小程序案例,你可以从这些案例中学习一下,然后再做自己的小程序. 1.商城小程序案例 商城小程序如今是比较常 ...
- 只要功夫深,菜鸟也能写出细节满满的古茗点单小程序
前言 写在项目前的话: 临近期末了,各学科纷纷结课,随之而来的是各个课设的纷至沓来.俗话说得好,大学生的生活前五个月是温水泡脚,那么最后一个月的就是将前五个月泡脚的水喝下去.作为一个平日里摸鱼摸惯的摸 ...
- Python爬虫系列之爬取某优选微信小程序全国店铺商品数据
Python爬虫系列之爬取某优选微信小程序全国商品数据 小程序爬虫接单.app爬虫接单.网页爬虫接单.接口定制.网站开发.小程序开发 > 点击这里联系我们 < 微信请扫描下方二维码 代码仅 ...
- 微信小程序将html转为wxml开发案例
微信小程序开发虽说是比较偏向前端开发,但是它们的语法结构又不太一样.例如,wxml跟html就有本质的不同,就拿a标签来说吧,wxml是不支持a标签的,还有就是wxml不兼容html,下面小编就针对这 ...
- Python3爬虫——用BeautifulSoup解析古诗文网
我们之前已经用Xpath分析过了古诗文网,但还是感觉有点麻烦,所以今天来讲BeautifulSoup库,它可以很方便的帮我们抓取网页的数据,同样也支持lxml解析器,下面我们来详细介绍: 安装Beau ...
- 爬取汽车之家图片 - scrapy - crawlspider - python爬虫案例
爬取汽车之家图片 需求:爬取汽车之家某一个汽车的图片 一. 普通scrapy 第一步 页面分析 目标url: https://car.autohome.com.cn/photolist/serie ...
- python爬取微信小程序源代码_【实战】CrawlSpider实现微信小程序社区爬虫
概述: 在人工智能来临的今天,数据显得格外重要.在互联网的浩瀚大海洋中,隐藏着无穷的数据和信息.因此学习网络爬虫是在今天立足的一项必备技能.本路线专门针对想要从事Python网络爬虫的同学而准备的,并 ...
最新文章
- Creating Lists
- Python中获取异常(try Exception)信息
- python接口自动化(二十四)--unittest断言——中(详解)
- JSP简单练习-定时刷新页面
- Java享元模式之字符串享元
- 使用jquery当页面打开时,将修改样式的点击事件绑定到Dom
- ROS( C++ )订阅 robot 的 path 话题
- xampp 配置虚拟主机
- 套用带标题行的表格样式_比格式刷好用10倍,原来Excel表格还有这么神奇的功能!...
- 使用Onedrive
- 对Java中字符串的进一步理解
- 计算机网络AD名词解释,计算机网络名词解释 AD是什么意思?
- sw2014计算机配置,SolidWorks 2014电脑配置要求
- CocosCreator之绳索摆动效果
- 联想服务器系统备份,操作演示:恢复预装系统前的数据备份方法
- dm8148 开发只boot启动参数vram=128简介
- Windows WSL2 安装Nvidia-Docker GPU 驱动Paddlepaddle
- 【CSDN软件工程师能力认证学习精选】不用框架,python实现卷积神经网络
- linux 时间 find,linux find 时间time
- 低成本实现三联屏拼接