scrapy框架实现百度图片爬虫
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 =
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 = for ok, x in result if ok]
if not image_path:
raise DropItem('Image Dowload Failed')
return item
在settings.py文件中加上这一行,即保存图片的文件夹,我这里是保存在当前目录下的images文件夹IMAGES_STORE = "./images"
支持分享
页:
[1]