当我们想要抓取一个页面的内容时,要做的第一件事不是写代码,而是分析页面,确定这是一个静态页面还是动态页面。抓取静态页面的方法十分简单,直接解析html源码再进行分析解析即可,如果不太明白,可以参考我上篇文章Scrapy抓取豆瓣电影信息,这里我主要讲述一下如何抓取动态页面。

抓取动态页面有两种方法:
第一种方法是采用第三方工具,模拟浏览器的行为,从而加载数据。比如:Selenium、PhantomJs。这种方法的优点在于不必考虑动态页面的各种变化多端,但是性能低。

第二种方法是分析页面,找到对应的请求接口,直接获取数据。这种方法的优点在于性能高,但缺点也显而易见,就是获取API接口比较麻烦。

我这里采用第二种方式抓取动态页面。

1.浏览器打开页面 http://image.so.com/z?ch=beauty,查看网页源代码,发现源码中没有图片信息,这是一个动态加载的页面,而且是ajax异步请求动态页面。

2.分析页面,提取API接口,通过F12,审查元素可以找到。

3.打开上面的url,发现传入的是json格式的数据,所以之后我们获取到response响应,要先用json.loads()解析数据。

4.观察API接口,可以发现有几个参数,ch、sn、listtype、temp,通过改变这些参数的值就能获取到不同的内容。

通过分析发现,ch参数代表图片分类,比如beauty就表示美女图片,sn表示图片的编号,比如0就表示1到30之间的图片,30就表示31到60之间的图片。

分析了这些参数,我们就确定了我们需要请求的url地址,此处的url不像静态页面中通过程序自动获取a标签中的href,而是需要我们自动设定,我们可以通过重写start_requests方法指定需要获取的url。

5.编写我们的spider

# -*- coding: utf-8 -*-
from json import loadsimport scrapyfrom urllib.parse import urlencodefrom image360.items import BeautyItemclass ImageSpider(scrapy.Spider):name = 'image'allowed_domains = ['image.so.com']# 重写Spider中的start_requests方法:指定开始urldef start_requests(self):base_url = 'http://image.so.com/zj?'param = {'ch': 'beauty', 'listtype': 'new', 'temp': '1'}# 可以根据需要爬取不同数量的图片,此处只爬取60张图片for page in range(2):param['sn'] = page * 30full_url = base_url + urlencode(param)yield scrapy.Request(url=full_url, callback=self.parse)def parse(self, response):# 获取到的内容是json数据# 用json.loads()解析数据# 此处的response没有contentmodel_dict = loads(response.text)for elem in model_dict['list']:item = BeautyItem()item['title'] = elem['group_title']item['tag'] = elem['tag']item['height'] = elem['cover_width']item['width'] = elem['cover_height']item['url'] = elem['qhimg_url']yield item

6.编写item,定义保存的字段


import scrapyclass BeautyItem(scrapy.Item):title = scrapy.Field()tag = scrapy.Field()height = scrapy.Field()width = scrapy.Field()url = scrapy.Field()

7.编写pipeline,完成数据持久化操作,这里包括下载图片和保存图片信息到mongo中。

Scrapy提供了一个 item pipeline ,来下载属于某个特定项目的图片,比如,当你抓取产品时,也想把它们的图片下载到本地,就可以通过图片管道实现。这在ImagesPipenine类中实现,提供了一个方便并具有额外特性的方法,来下载并本地存储图片。这个类中提供了很多处理图片的方法,想要了解详细内容可以查看官方文档中文版

# -*- coding: utf-8 -*-import logging
import pymongo
import scrapyfrom scrapy.exceptions import DropItem
from scrapy.pipelines.images import ImagesPipelinelogger = logging.getLogger('SaveImagePipeline')# 继承ImagesPipenine类,这是图片管道
class SaveImagePipeline(ImagesPipeline):"""下载图片"""def get_media_requests(self, item, info):# 此方法获取的是requests 所以用yield 不要returnyield scrapy.Request(url=item['url'])def item_completed(self, results, item, info):"""文件下载完成之后,返回一个列表 results列表中是一个元组,第一个值是布尔值,请求成功会失败,第二个值的下载到的资源"""if not results[0][0]:# 如果下载失败,就抛出异常,并丢弃这个item# 被丢弃的item将不会被之后的pipeline组件所处理raise DropItem('下载失败')# 打印日志logger.debug('下载图片成功')return itemdef file_path(self, request, response=None, info=None):"""返回文件名"""return request.url.split('/')[-1]class SaveToMongoPipeline(object):"""保存图片信息到数据库"""def __init__(self, mongodb_server, mongodb_port, mongodb_db, mongodb_collection):self.mongodb_server = mongodb_serverself.mongodb_port = mongodb_portself.mongodb_db = mongodb_dbself.mongodb_collection = mongodb_collectiondef open_spider(self, spider):# 当spider被开启时,这个方法被调用self.connection = pymongo.MongoClient(self.mongodb_server, self.mongodb_port)db = self.connection[self.mongodb_db]self.collection = db[self.mongodb_collection]def close_spider(self, spider):# 当spider被关闭时,这个方法被调用。self.connection.close()# 依赖注入@classmethoddef from_crawler(cls, crawler):# cls() 会调用初始化方法return cls(crawler.settings.get('MONGODB_SERVER'),crawler.settings.get('MONGODB_PORT'),crawler.settings.get('MONGODB_DB'),crawler.settings.get('MONGODB_COLLECTION'))def process_item(self, item, spider):post = {'title': item['title'], 'tag': item['tag'],'width': item['width'], 'height': item['height'], 'url': item['url']}self.collection.insert_one(post)return item

8.编写settings,完成配置,此处只把需要配置的内容写了出来。

BOT_NAME = 'image360'SPIDER_MODULES = ['image360.spiders']
NEWSPIDER_MODULE = 'image360.spiders'# Crawl responsibly by identifying yourself (and your website) on the user-agent
USER_AGENT = 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) ' \'Chrome/67.0.3396.79 Safari/537.36'# Obey robots.txt rules
ROBOTSTXT_OBEY = False# Configure maximum concurrent requests performed by Scrapy (default: 16)
CONCURRENT_REQUESTS = 1# 随机延迟,设定随机延迟,使爬虫更像浏览器的行为
RANDOMIZE_DOWNLOAD_DELAY = True
# 延迟时间
DOWNLOAD_DELAY = 3# 数据库信息
MONGODB_SERVER = '服务器地址'
MONGODB_PORT = 27017
MONGODB_DB = 'image360'
MONGODB_COLLECTION = 'image'# 日志
LOG_LEVEL = 'DEBUG'# 数字越小越先执行
ITEM_PIPELINES = {'image360.pipelines.SaveImagePipeline': 300,'image360.pipelines.SaveToMongoPipeline': 330,
}# 配置图片保存地址,会自动创建文件夹
IMAGES_STORE = './resources'

9.启动spider
在启动spider之前,我们还需要安装几个包,pypiwin32、pilllow、pymongo

pip install pypiwin32
pip install pillow
pip install pymongo

安装完成之后就可以启动spider了

scrapy crawl image

10.查看结果:
获取到的图片返回的内容:

保存在指定路径的图片:

一个爬取动态页面并且下载图片的爬虫就完成了,其实写起来很简单,关键是需要分析API接口,重写start_requests方法。

Scrapy爬取动态页面下载图片(以抓取360图片为例)相关推荐

  1. 抓取百度页面html,百度会抓取页面代码中的注释内容吗

    百度会抓取页面代码中的注释内容吗 内容导读:百度会抓取页面代码中的注释内容吗?答案是百度会抓取,但是在提取正文的时候会直接忽略掉,也就是说页面代码的注释内容不会影响到页面质量,所以大家尽管放心. 问题 ...

  2. 爬取动态网页数据的软件-抓取动态网页数据的工具

    爬取动态网页数据,随着时代的进步,互联网的发展,不管是企业还是个人都知道了数据的重要性.今天给大家分享一款免费爬取动态网页数据的软件.只要点点鼠标就能轻松爬取到你想要的数据,不管是导出还是自动发布都支 ...

  3. php抓取今日头条,分析Ajax来抓取今日头条街拍美图

    一.介绍 还是根据崔大大的视频来码的文章,不得不说,抓取文件并下载下来比抓取网页内容信息复杂多了 二.流程 目标站点分析 用浏览器打开今日头条输入'街拍',打开审查元素,点击'图集' 1.首先我们要找 ...

  4. scrapy爬取动态页面

    文章目录 简介 查看目标网站 代码部分 简介 现在在整理原来写过的东西,这是一个比较简单的爬虫项目,就是进行动态页面的爬取,主要的难点是实现模拟点击. 查看目标网站 查看目标网站: 但是这不是我们的目 ...

  5. 笨笨图片批量抓取下载 V0.2 beta[C# | WinForm | 正则表达式 | HttpWebRequest | Async异步编程]...

    一.     先贴一张图,这个界面就是程序的主界面了: 二.     部分代码说明(主要讲解异步分析和下载): 异步分析下载采取的策略是同时分析同时下载,即未等待数据全部分析完毕就开始把已经分析出来的 ...

  6. 蜘蛛能抓取thinkphp的html页面,搜索引擎的蜘蛛是如何爬的,如何吸引蜘蛛来抓取页面...

    搜索引擎的蜘蛛是如何爬的,如何吸引蜘蛛来抓取页面 搜索引擎的工作过程大体可以分成三个阶段: (1)爬行和抓取:搜索引擎蜘蛛通过跟踪链接发现和访问页面,读取页面HTML代码,存到数据库. (2)预处理: ...

  7. python爬虫怎么爬同一个网站的多页数据-如何用Python爬数据?(一)网页抓取

    如何用Python爬数据?(一)网页抓取 你期待已久的Python网络数据爬虫教程来了.本文为你演示如何从网页里找到感兴趣的链接和说明文字,抓取并存储到Excel. 需求 我在公众号后台,经常可以收到 ...

  8. python爬网站数据实例-如何用Python爬数据?(一)网页抓取

    如何用Python爬数据?(一)网页抓取 你期待已久的Python网络数据爬虫教程来了.本文为你演示如何从网页里找到感兴趣的链接和说明文字,抓取并存储到Excel. 需求 我在公众号后台,经常可以收到 ...

  9. html如何让图片不能抓取,Jsoup+Htmlunit抓取图片遇到坑

    Jsoup简介 Jsoup是用于解析HTML,就类似XML解析器用于解析XML. Jsoup它解析HTML成为真实世界的HTML. 能用Jsoup实现什么? ●从URL,文件或字符串中刮取并解析HTM ...

最新文章

  1. javascript的知识总结
  2. ThinkPHP多应用/多模块配置
  3. golang函数:命名返回值代码示例
  4. Matalab类定义
  5. Qt下简单的文件读取
  6. Base64与文件(docx)流的加密和解密
  7. dataloader 源码_[莫烦 PyTorch 系列教程] 3.5 – 数据读取 (Data Loader)
  8. postgresql 参数替换 游标_解决postgresql和oracle如何把游标cursor数据存到数组array
  9. xerces 64位 linux安装,linux安装xml开发包xerces-c
  10. 电容尺寸、封装及PCB库
  11. 没有测量就没有管理,怀念DNW和复习盖洛普Q12
  12. 青龙面板2.9,以及wskey自动转换ck配置
  13. 楼兰宝盒显示网络服务器无响应,捷达vs5-圈里有谁跟我一样,安装了楼兰宝盒后,用手机启动车子出现无钥匙解锁失灵时候使坏,和前部辅助系统出现故障问题,不用手机启动就没事...
  14. 图像处理——分水岭算法
  15. 香港伦敦金交易平台排行榜(2022最新版)
  16. 25个最适合Crossfit的WordPress主题(2020)
  17. 公安联勤指挥调度实战应用系统软件平台解决方案
  18. 深入理解文字高度和行高的设置
  19. android.view.WindowLeaked报错的解决方案
  20. CS294-112 深度强化学习 秋季学期(伯克利)NO.9 Learning policies by imitating optimal controllers...

热门文章

  1. 尚学堂Java学习笔记
  2. qt编写网易云界面(10)----排行榜模块
  3. C++ 实验十四结构程序设计
  4. Linux 文字转语音
  5. 财路网每日原创推送:超90%容错共识算法,如何实现?
  6. 网址转换为ip(数字)地址
  7. python 爬取亚马逊评论_用Python爬取了三大相亲软件评论区,结果...
  8. TCP与Web服务器
  9. 数字电路3-8译码器
  10. centos 7, 安装网卡驱动过程记录