Scrapy实战篇(六)之Scrapy配合Selenium爬取京东信息(上)
在之前的一篇实战之中,我们已经爬取过京东商城的文胸数据,但是前面的那一篇其实是有一个缺陷的,不知道你看出来没有,下面就来详细的说明和解决这个缺陷。
我们在京东搜索页面输入关键字进行搜索的时候,页面的返回过程是这样的,它首先会直接返回一个静态的页面,页面的商品信息大致是30个,之所以说是大致,因为有几个可能是广告商品,之后,当我们鼠标下滑的使用,京东后台使用Ajax技术加载另外的30个商品数据,我们看上去是60个数据,其实这60个数据是分两次加载出来的,而且只是在你鼠标下滑到一定的位置才会加载那另外的30个数据。
当你点击页面最后的第二页的时候,仔细观察新的url你会发现它的页面显示是第三页。
下面是初始第一面和点击第二页之后的url
# 第一页的url
https://search.jd.com/Search?keyword=%E6%89%8B%E6%9C%BA&enc=utf-8&qrst=1&rt=1&stop=1&vt=2&wq=%E6%89%8B%E6%9C%BA&cid2=653&cid3=655&page=1&s=1&click=0
# 点击第二页的url
https://search.jd.com/Search?keyword=%E6%89%8B%E6%9C%BA&enc=utf-8&qrst=1&rt=1&stop=1&vt=2&wq=%E6%89%8B%E6%9C%BA&cid2=653&cid3=655&page=3&s=59&click=0
page参数一个是1,一个是3。
因此可以得知,京东的第二页的信息是使用Ajax加载出来的,而不是直接请求url的形式。如果我们想要拿到另外的30个信息,一方面是需要js渲染,另一方面是实现滚动条下拉,触发Ajax请求。
知道了过程,下面就是着手解决这个问题,由于Scrapy框架只能加载静态数据,因此我们需要另外的工具来配合Scrapy实现爬取页面的完整信息。
我们的技术路线是这样的,使用selenium加Firefox来实现目的。
实现的过程是这样的,将selenium作为scrapy的下载中间件,执行js脚本实现滚动条的下拉,并且实现js的渲染。
下面就来演示。
spider.py文件
from scrapy import Spider,Request
from selenium import webdriver
class JingdongSpider(Spider):
name = 'jingdong'
def __init__(self):
self.browser = webdriver.Firefox()
self.browser.set_page_load_timeout(30)
def closed(self,spider):
print("spider closed")
self.browser.close()
def start_requests(self):
start_urls = ['https://search.jd.com/Search?keyword=%E6%96%87%E8%83%B8&enc=utf-8&qrst=1&rt=1&stop=1&vt=2&suggest=1.his.0.0&page={}&s=1&click=0'.format(str(i)) for i in range(1,2,2)]
for url in start_urls:
yield Request(url=url, callback=self.parse)
def parse(self, response):
selector = response.xpath('//ul[@class="gl-warp clearfix"]/li')
print(len(selector))
print('---------------------------------------------------')
这里将webdriver定义在spider文件的好处是,不需要每一次请求url都打开和关闭浏览器。
其中的closed()方法,是在爬虫程序结束之后,自动关闭浏览器。
由于这里是演示之用,我们就以一个页面来测试,看一下最后的结果是不是返回60条数据,如果是60条左右就证明我们的selenium起作用了,如果仅仅是30条左右的数据,就证明失败。
middlewares.py
下面的这个文件是主要逻辑实现
from scrapy.http import HtmlResponse
from selenium.common.exceptions import TimeoutException
import time
class SeleniumMiddleware(object):
def process_request(self, request, spider):
if spider.name == 'jingdong':
try:
spider.browser.get(request.url)
spider.browser.execute_script('window.scrollTo(0, document.body.scrollHeight)')
except TimeoutException as e:
print('超时')
spider.browser.execute_script('window.stop()')
time.sleep(2)
return HtmlResponse(url=spider.browser.current_url, body=spider.browser.page_source,
encoding="utf-8", request=request)
在程序中,我们执行了js脚本,来实现滚动条下拉,触发Ajax请求,之后我们简短的等待,来加载Ajax。 在scrapy官方文档中,对下载中间件有着比较详细的说明,当某个下载中间件返回的是response对象的时候,之后的下载中间件将不会被继续执行,而是直接返回response对象。
之后,我们只需要在设置中将当前的下载中间件添加到settings.py文件中,就可以实现了。
运行程序,会发现自动打开了Firefox浏览器,并且实现了滚动条的下拉,关闭浏览器。控制台打印信息如下。

不妨多试验几个页面,会发现效果也是一样的。
Scrapy实战篇(六)之Scrapy配合Selenium爬取京东信息(上)的更多相关文章
- Scrapy实战篇(七)之Scrapy配合Selenium爬取京东商城信息(下)
之前我们使用了selenium加Firefox作为下载中间件来实现爬取京东的商品信息.但是在大规模的爬取的时候,Firefox消耗资源比较多,因此我们希望换一种资源消耗更小的方法来爬取相关的信息. 下 ...
- Scrapy实战篇(八)之Scrapy对接selenium爬取京东商城商品数据
本篇目标:我们以爬取京东商城商品数据为例,展示Scrapy框架对接selenium爬取京东商城商品数据. 背景: 京东商城页面为js动态加载页面,直接使用request请求,无法得到我们想要的商品数据 ...
- selenium模块使用详解、打码平台使用、xpath使用、使用selenium爬取京东商品信息、scrapy框架介绍与安装
今日内容概要 selenium的使用 打码平台使用 xpath使用 爬取京东商品信息 scrapy 介绍和安装 内容详细 1.selenium模块的使用 # 之前咱们学requests,可以发送htt ...
- 爬虫系列(十三) 用selenium爬取京东商品
这篇文章,我们将通过 selenium 模拟用户使用浏览器的行为,爬取京东商品信息,还是先放上最终的效果图: 1.网页分析 (1)初步分析 原本博主打算写一个能够爬取所有商品信息的爬虫,可是在分析过程 ...
- 利用selenium爬取京东商品信息存放到mongodb
利用selenium爬取京东商城的商品信息思路: 1.首先进入京东的搜索页面,分析搜索页面信息可以得到路由结构 2.根据页面信息可以看到京东在搜索页面使用了懒加载,所以为了解决这个问题,使用递归.等待 ...
- 使用Selenium爬取京东电商数据(以手机商品为例)
进入京东(https://www.jd.com)后,我如果搜索特定的手机产品,如oppo find x2,会先出现如下的商品列表页: 如果点击进入其中一个商品会进入到如下图所示的商品详情页,可以看到用 ...
- 爬虫(十七):Scrapy框架(四) 对接selenium爬取京东商品数据
1. Scrapy对接Selenium Scrapy抓取页面的方式和requests库类似,都是直接模拟HTTP请求,而Scrapy也不能抓取JavaScript动态谊染的页面.在前面的博客中抓取Ja ...
- Python Scrapy的QQ音乐爬虫 音乐下载、爬取歌曲信息、歌词、精彩评论
QQ音乐爬虫(with scrapy)/QQ Music Spider UPDATE 2019.12.23 已实现对QQ音乐文件的下载,出于版权考虑,不对此部分代码进行公开.此项目仅作为学习交流使用, ...
- 基于selenium爬取京东
爬取iphone 注意:browser对象会发生变化,当对当前网页做任意操作时 import time from selenium import webdriver from selenium.web ...
随机推荐
- Parencodings(模拟)
ZOJ Problem Set - 1016 Parencodings Time Limit: 2 Seconds Memory Limit: 65536 KB Let S = s1 s2 ...
- TED_Topic2:My desperate journey with a human smuggler
My desperate journey with a human smuggler By Barat Ali Batoor When I was a child there was a toy wh ...
- HNOI2019退役祭
对你没看错,是退役祭. Day -2 春游.话说为什么又是植物园? Day -1 白天上文化课,晚上给机房其它童鞋出题. Day 0 给他们考试,然后颓3Dmaze,毕竟没网 Day 1 车上复习了下 ...
- 【leetcode 简单】第五十题 位1的个数
编写一个函数,输入是一个无符号整数,返回其二进制表达式中数字位数为 ‘1’ 的个数(也被称为汉明重量). 示例 : 输入: 11 输出: 3 解释: 整数 11 的二进制表示为 00000000000 ...
- C语言二分查找
#include <stdio.h> /* 二分查找条件: 1.有序序列 2.数据在数组中 */ int baseBinarySearch(int a[],int h,int k) { ; ...
- 可怕的npm蠕虫
https://hackernoon.com/im-harvesting-credit-card-numbers-and-passwords-from-your-site-here-s-how-9a8 ...
- C - Contest Setting Gym - 101982C dp 补题
题目链接:https://vjudge.net/contest/273260#problem/C 学习了一下别人的思路,首先去重,然后离散化. dp数组开二维,每一次更新,状态转移方程,dp[ i ] ...
- 好消息! 不用再羡慕Python有jupyter 我R也有Notebook了【附演示视频】
熟悉python的朋友可能知道jupyter notebook.它是一个Web应用程序,允许你创建和共享代码,方程,可视化和说明性文本文档.现在,我们可以在RStudio中实现R Notebook的功 ...
- docker安装总结 linux红帽系列
由于Docker限制分为两个版本CE和EE,所以之前yum里面的docker是老版本,需要先进行卸载,现在的包名叫做docker-ce yum remove docker docker-common ...
- Python3 断言
#!/usr/bin/env python # _*_ coding:utf-8 _*_ # Author:CarsonLi ''' 断言一般用于后面有非常重要的操作,需要使用前面的数据,而且不容许出 ...