Scrapy抓取动态内容、下载图片和导入selenium
爬取动态内容
- 在网页中,有些数据是ajax异步加载,而这些数据我们在用爬虫直接抓取页面的时候并不能抓取到
这时,我们可以通过直接通过抓取数据接口的方式来获取数据
- 首先在要抓取的页面打开开发者工具
- 进入network下面的XHR,刷新页面抓取异步的数据包
- 分析数据包的url,找到数据加载规则
- 分析数据字段,提取需要的字段信息
下面是抓取360图片的一段代码,因为我们要自己定义要抓取的页面,所以不再需要start_url这个列表,并重写了它的start_requests方法。
# -*- coding: utf-8 -*-
from json import loads
from urllib.parse import urlencode
import scrapy
from img360.items import ImgItem
class ImageSpider(scrapy.Spider):
name = 'image'
allowed_domains = ['image.so.com']
# 重写这个方法
def start_requests(self):
base_url = 'http://image.so.com/zj?'
param = {
'ch': 'beauty', 'listtype': 'new', 'temp': 1}
for page in range(10):
param['sn'] = page * 30
# 可以将字典里面的数据加在url后面, 如果有中文会自动变成%编码
full_url = base_url + urlencode(param)
yield scrapy.Request(url=full_url, callback=self.parse)
def parse(self, response):
# 因为返回的是一个json数据,所以用json.loads处理数据
# 数据通过浏览器的开发者工具中network中进行动态找包,分析包
model_dict = loads(response.text)
for elem in model_dict['list']:
item = ImgItem()
item['title'] = elem['group_title']
item['tag'] = elem['tag']
item['width'] = elem['cover_width']
item['height'] = elem['cover_height']
item['url'] = elem['qhimg_url']
yield item
下载图片到本地
- Scrapy中给我们封装好了下载图片的方法,只需要我们在pipelines文件中继承ImagesPipeline,并重写它的get_media_requests,item_completed, file_path 方法。并在settings中配置到下载路径,这样就可以在获取图片时,直接将图片下载到本地。
- 具体的实现方法,参照下面的代码
# -*- 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 logging
import pymongo
from scrapy import Request
from scrapy.exceptions import DropItem
from scrapy.pipelines.images import ImagesPipeline
# 修改logging的名字
logging = logging.getLogger('SaveImgPipeline')
# 需要pip install pillow
class SaveImgPipeline(ImagesPipeline):
# 图片的url
def get_media_requests(self, item, info):
yield Request(url=item['url'])
# return super().get_media_requests(item, info)
def item_completed(self, results, item, info):
# results会返回一个列表,第一个值是一个元组,里面的第一个数据是数据是否下载成功的布尔值
if not results[0][0]:
raise DropItem('下载失败')
logging.debug('下载完成')
return item
# return super().item_completed(results, item, info)
def file_path(self, request, response=None, info=None):
filename = request.url.split('/')[-1]
# 只需要返回文件名,文件路径会自动找到settings中IMAGES_STORE