TA的每日心情 | 无聊 2024-9-19 09:07 |
---|
签到天数: 11 天 连续签到: 2 天 [LV.3]测试连长
|
scrapy框架实现百度图片爬虫
程序的环境为windows + pycharm + python3.6 + scrapy
思路:百度图片加载是基于ajax数据加载的,图片的url都藏在后台发送的json文件中,所以需要在开发者模式xhr中,找到对应的json请求,然后构造url发送即可得到返回的json文件,然后用正则表达式提取出图片的url,然后用scrapy框架构造爬虫,下载速度非常快,难度也不大。
- 构造url时,如果搜索内容有中文,可以先单独在终端导入 from urllib.parse import quote
- name = "搜索内容"
- newName = quote(name)
- print(newName)
- 即可将中文生成相应的url格式
- 如中文'赵丽颖'为'%E8%B5%B5%E4%B8%BD%E9%A2%96'
- 将爬虫url中的word=后面的内容替换就行
复制代码 爬虫函数
- # -*- coding: utf-8 -*-
- import re
- import scrapy
- from baidu.items import BaiduItem
- class DuduSpider(scrapy.Spider):
- # 爬虫名
- name = 'dudu'
- # 爬虫允许的爬取域名范围,最好根据你所要爬取的网站来确定,不能乱写,否则会搜索不到内容,使爬虫不受控制
- allowed_domains = ['image.baidu.com']
- #构建url的起始值offset,具体由网页分析后确定
- offset = 90
- #此处url的'https://'一定要写,不然会报错,而且不容易找出
- url = 'https://image.baidu.com/search/acjson?tn=resultjson_com&ipn=rj&ct=201326592&is=&fp=result&cl=2&lm=-1&ie=utf-8&oe=utf-8&adpicid=&st=-1&z=&ic=0&word=Tara&s=&se=&tab=&width=&height=&face=0&istype=2&qc=&nc=1&fr=&expermode=&pn='
- #起始url,列表内字符串的拼接
- start_urls = [url + str(offset)]
- def parse(self, response):
- #使用scrapy shell 返回的内容为json格式,正则匹配出图片链接并提取
- pattern = re.compile(r'"middleURL":"(.*?)",', re.S)
- #此datas返回的是一个正则表达式列表,可迭代取出里面的url
- datas = re.findall(pattern, response.text)
- for data in datas:
- #实例化item
- item = BaiduItem()
- # print("图片链接是:", data)
- item['imageLink'] = data
- #生成器,返回给pipelineItem文件
- # 由一个url获取一个图片的url列表,列表内有若干个图片链接url,依次获取发送图片链接的url,直至发送完,跳出循环
- yield item
- #跳出循环后offset自增30(网页决定)
- self.offset += 30
- #调用此生成器,并发送下一个网页url,回调函数调用self.parse自身,再次循环处理列表中的图片链接url,循环往复获取图片
- yield scrapy.Request(self.url + str(self.offset), callback=self.parse)
复制代码pipelines.py文件 - # -*- coding: utf-8 -*-
- # Define your item pipelines here
- #
- # Don't forget to add your pipeline to the ITEM_PIPELINES setting
- # See: https://doc.scrapy.org/en/latest/topics/item-pipeline.html
- import scrapy
- from scrapy.exceptions import DropItem
- from scrapy.utils.project import get_project_settings
- from scrapy.pipelines.images import ImagesPipeline
- class BaiduPipeline(ImagesPipeline):
- #使用settings.py中的设置
- IMAGES_STORE = get_project_settings().get('IMAGES_STORE')
- # 此函数的第一个对象request就是当前下载对应的scrapy.Request对象,这个方法永汉返回保存的文件名,将图片链接的最后一部分党文文件名,确保不会重复
- def file_path(self, request, response=None, info=None):
- url = request.url
- file_name = url.split('/')[-1]
- return file_name
- # 第一个item对象是爬取生成的Item对象,可以将他的url字段取出来,直接生成scrapy.Request对象,此Request加入到调度队列,等待被调度,然后执行下载
- def get_media_requests(self, item, info):
- image_url = item["imageLink"]
- yield scrapy.Request(image_url)
- # 这是单个Item完成下载时的处理方法,各种原因,并不是每张图片都会下载成功,此方法可以剔除下载失败的图片
- # result是该Item对应的下载结果,是一个列表形式,列表每个元素是一个元组,其中包含了下载成功与失败的信息,这里遍历下载结果,找出所有下载成功的列表,如果列表为空,那么此Item对应的图片链接下载失败,随即跑出异常DropItem,该Item忽略,否则返回Item,该Item有效
- def item_completed(self, result, item, info):
- image_path = [x["path"] for ok, x in result if ok]
- if not image_path:
- raise DropItem('Image Dowload Failed')
- return item
复制代码在settings.py文件中加上这一行,即保存图片的文件夹,我这里是保存在当前目录下的images文件夹 - IMAGES_STORE = "./images"
复制代码
|
|