51Testing软件测试论坛

标题: scrapy框架实现百度图片爬虫 [打印本页]

作者: 八戒你干嘛    时间: 2019-6-17 17:05
标题: scrapy框架实现百度图片爬虫
scrapy框架实现百度图片爬虫
程序的环境为windows + pycharm + python3.6 + scrapy
思路:百度图片加载是基于ajax数据加载的,图片的url都藏在后台发送的json文件中,所以需要在开发者模式xhr中,找到对应的json请求,然后构造url发送即可得到返回的json文件,然后用正则表达式提取出图片的url,然后用scrapy框架构造爬虫,下载速度非常快,难度也不大。
  1. 构造url时,如果搜索内容有中文,可以先单独在终端导入 from urllib.parse import quote
  2. name = "搜索内容"
  3. newName = quote(name)
  4. print(newName)
  5. 即可将中文生成相应的url格式
  6. 如中文'赵丽颖'为'%E8%B5%B5%E4%B8%BD%E9%A2%96'
  7. 将爬虫url中的word=后面的内容替换就行
复制代码
爬虫函数
  1. # -*- coding: utf-8 -*-
  2. import re
  3. import scrapy
  4. from baidu.items import BaiduItem


  5. class DuduSpider(scrapy.Spider):
  6.     # 爬虫名
  7.     name = 'dudu'
  8.     # 爬虫允许的爬取域名范围,最好根据你所要爬取的网站来确定,不能乱写,否则会搜索不到内容,使爬虫不受控制
  9.     allowed_domains = ['image.baidu.com']
  10.     #构建url的起始值offset,具体由网页分析后确定
  11.     offset = 90
  12.     #此处url的'https://'一定要写,不然会报错,而且不容易找出
  13.     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='
  14.     #起始url,列表内字符串的拼接
  15.     start_urls = [url + str(offset)]

  16.     def parse(self, response):
  17.         #使用scrapy shell 返回的内容为json格式,正则匹配出图片链接并提取
  18.         pattern = re.compile(r'"middleURL":"(.*?)",', re.S)
  19.         #此datas返回的是一个正则表达式列表,可迭代取出里面的url
  20.         datas = re.findall(pattern, response.text)
  21.         for data in datas:
  22.             #实例化item
  23.             item = BaiduItem()
  24.             # print("图片链接是:", data)
  25.             item['imageLink'] = data
  26.             #生成器,返回给pipelineItem文件
  27.             # 由一个url获取一个图片的url列表,列表内有若干个图片链接url,依次获取发送图片链接的url,直至发送完,跳出循环
  28.             yield item
  29.         #跳出循环后offset自增30(网页决定)
  30.         self.offset += 30
  31.         #调用此生成器,并发送下一个网页url,回调函数调用self.parse自身,再次循环处理列表中的图片链接url,循环往复获取图片
  32.         yield scrapy.Request(self.url + str(self.offset), callback=self.parse)
复制代码

pipelines.py文件

  1. # -*- coding: utf-8 -*-

  2. # Define your item pipelines here
  3. #
  4. # Don't forget to add your pipeline to the ITEM_PIPELINES setting
  5. # See: https://doc.scrapy.org/en/latest/topics/item-pipeline.html
  6. import scrapy

  7. from scrapy.exceptions import DropItem
  8. from scrapy.utils.project import get_project_settings
  9. from scrapy.pipelines.images import ImagesPipeline


  10. class BaiduPipeline(ImagesPipeline):
  11.     #使用settings.py中的设置
  12.     IMAGES_STORE = get_project_settings().get('IMAGES_STORE')

  13.     # 此函数的第一个对象request就是当前下载对应的scrapy.Request对象,这个方法永汉返回保存的文件名,将图片链接的最后一部分党文文件名,确保不会重复
  14.     def file_path(self, request, response=None, info=None):
  15.         url = request.url
  16.         file_name = url.split('/')[-1]
  17.         return file_name

  18.     # 第一个item对象是爬取生成的Item对象,可以将他的url字段取出来,直接生成scrapy.Request对象,此Request加入到调度队列,等待被调度,然后执行下载
  19.     def get_media_requests(self, item, info):
  20.         image_url = item["imageLink"]
  21.         yield scrapy.Request(image_url)

  22.     # 这是单个Item完成下载时的处理方法,各种原因,并不是每张图片都会下载成功,此方法可以剔除下载失败的图片
  23.     # result是该Item对应的下载结果,是一个列表形式,列表每个元素是一个元组,其中包含了下载成功与失败的信息,这里遍历下载结果,找出所有下载成功的列表,如果列表为空,那么此Item对应的图片链接下载失败,随即跑出异常DropItem,该Item忽略,否则返回Item,该Item有效
  24.     def item_completed(self, result, item, info):
  25.         image_path = [x["path"] for ok, x in result if ok]
  26.         if not image_path:
  27.             raise DropItem('Image Dowload Failed')
  28.         return item

复制代码

在settings.py文件中加上这一行,即保存图片的文件夹,我这里是保存在当前目录下的images文件夹

  1. IMAGES_STORE = "./images"
复制代码







作者: Miss_love    时间: 2020-12-30 15:12
支持分享




欢迎光临 51Testing软件测试论坛 (http://bbs.51testing.com/) Powered by Discuz! X3.2