小白学 Python 爬虫:Selenium 获取某大型电商网站商品信息
目标
先介绍下我们本篇文章的目标,如图:
本篇文章计划获取商品的一些基本信息,如名称、商店、价格、是否自营、图片路径等等。
准备
首先要确认自己本地已经安装好了 Selenium 包括 Chrome ,并已经配置好了 ChromeDriver 。如果还没安装好,可以参考前面的前置准备。
分析
接下来我们就要分析一下了。
首先,我们的搜索关键字是 iPhone
,直接先翻到最后一页看下结果,发现有好多商品并不是 iPhone
,而是 iPhone
的手机壳,这个明显不是我们想要的结果,小编这里选择了一下品牌 Apple
,再翻到最后一页,这次就全都是手机了。
先把地址栏的地址 Copy 出来看一下,里面有很多无效参数:
https://search.jd.com/search?keyword=iPhone&enc=utf-8&qrst=1&rt=1&stop=1&vt=2&ev=exbrand_Apple%5E&page=199&s=5933&click=0
如果问小编怎么知道是无效参数还是有效参数,emmmmmmmmm
这个要么靠经验,一般大网站的参数的命名都是比较规范的,当然也不排除命名不规范的。还有一种办法就是试,小编这边试出来的结果是这样滴:
https://search.jd.com/Search?keyword=iPhone&ev=exbrand_Apple
第一个参数 keyword
就是我们需要的商品名称,第二个参数 ev
是品牌的参数。
接下来我们看如何获取商品的详细信息,我们使用 F12 打开开发者模式,使用看下具体的信息都放在哪里:
可以看到,我们想要获取的信息在这个页面的 DOM 节点中都能获取到。
接下来因为我们是使用 Selenium 来模拟浏览器访问电商网站,所以后续的接口分析也就不需要做了,直接获取浏览器显示的内容的源代码就可以轻松获取到各种信息。
获取商品列表页面
首先,我们需要构造一个获取商品列表页面的 URL ,这个上面已经得到了,接下来就是使用 Selenium 来获取这个页面了:
from selenium import webdriver
from selenium.common.exceptions import TimeoutException
driver = webdriver.Chrome()
driver.implicitly_wait(10)
driver.set_window_size(1280,800)
def index_page(page):
"""
抓取索引页
:param page: 页码
"""
print('正在爬取第', str(page), '页数据')
try:
url = 'https://search.jd.com/Search?keyword=iPhone&ev=exbrand_Apple'
driver.get(url)
if page > 1:
input = driver.find_element_by_xpath('//*[@id="J_bottomPage"]/span[2]/input')
button = driver.find_element_by_xpath('//*[@id="J_bottomPage"]/span[2]/a')
input.clear()
input.send_keys(page)
button.click()
get_products()
except TimeoutException:
index_page(page)
这里我们依然使用隐式等待来进行 URL 访问,这里小编通过 xpath 的方式获取到了整个页面最下面的翻页组件:
小编这里的翻页实际上是使用这里的输入框和后面的确认按钮进行的。
获取商品详细数据
这里其实有一个坑,JD 的首页上的图片是懒加载的,就是当页面的滚动条没有滚到这个图片可以显示在屏幕上的位置的时候,这个图片是不会加载出来的。这就造成了小编一开始的只能获取到前 4 个商品的图片地址。
小编后来想了个办法,使用 JavaScript 来模拟滚动条滚动,先将所有的图片加载出来,然后再进行数据的获取,代码如下:
def get_products():
"""
提取商品数据
"""
js = '''
timer = setInterval(function(){
var scrollTop=document.documentElement.scrollTop||document.body.scrollTop;
var ispeed=Math.floor(document.body.scrollHeight / 100);
if(scrollTop > document.body.scrollHeight * 90 / 100){
clearInterval(timer);
}
console.log('scrollTop:'+scrollTop)
console.log('scrollHeight:'+document.body.scrollHeight)
window.scrollTo(0, scrollTop+ispeed)
}, 20)
'''
driver.execute_script(js)
time.sleep(2.5)
html = driver.page_source
doc = PyQuery(html)
items = doc('#J_goodsList .gl-item .gl-i-wrap').items()
i = 0
for item in items:
insert_data = {
'image': item.find('.p-img a img').attr('src'),
'price': item.find('.p-price i').text(),
'name': item.find('.p-name em').text(),
'commit': item.find('.p-commit a').text(),
'shop': item.find('.p-shop a').text(),
'icons': item.find('.p-icons .goods-icons').text()
}
i += 1
print('当前第', str(i), '条数据,内容为:' , insert_data)
中间那段 js 就是模拟滚动条向下滚动的代码,这里小编做了一个定时任务,这个定时任务将整个页面的长度分成了 100 份,每 20 ms 就向下滚动 1% ,共计应该总共 2s 可以滚到最下面,这里下面做了 2.5s 的睡眠,保证这个页面的图片都能加载出来,最后再获取页面上的数据。
主体代码到这里就结束了,剩下的代码无非就是将数据保存起来,不管是保存在数据中还是保存在 Excel 中,或者是 CSV 中,又或者是纯粹的文本文件 txt 或者是 json ,都不难,小编这次就不写了,希望大家能自己完善下这个代码。
运行的时候,可以看到一个浏览器弹出来,然后滚动条自动以比较顺滑的速度滚到最下方(小编为了这个顺滑的速度调了很久),确保所有图片都加载出来,再使用 pyquery 获取相关的数据,最后组成了一个 json 对象,给大家看下抓取下来的结果吧:
Chrome 无界面模式
我们在爬取数据的时候,弹出来一个浏览器总感觉有点老不爽了,可以使用如下命令将这个浏览器隐藏起来,不过需要的是 Chrome 比较新的版本。
# 开启无窗口模式
chrome_options = webdriver.ChromeOptions()
chrome_options.add_argument('--headless')
driver = webdriver.Chrome(chrome_options=chrome_options)
首先,创建 ChromeOptions
对象,接着添加 headless
参数,然后在初始化 Chrome 对象的时候通过 chrome_options
传递这个 ChromeOptions
对象,这样我们就可以成功启用 Chrome 的Headless模式了。
FireFox
如果我们不想使用 Chrome 浏览器,还可以使用 FireFox 浏览器,前提是需要安装好 FireFox 和对应的驱动 GeckoDriver ,并且完成相关配置,不清楚如何安装的同学可以翻一翻前面的前置准备。
我们需要切换 FireFox 浏览器的时候,异常的简单,只需要修改一句话就可以了:
driver = webdriver.Firefox()
这里我们修改了 webdriver 初始化的方式,这样在接下来的操作中就会自动使用 FireFox 浏览器了。
如果 Firefox 也想开启无界面模式的话,同样也是可以的,和上面 Chrome 开启无界面模式大同小异:
# FireFox 开启无窗口模式
firefox_options = webdriver.FirefoxOptions()
firefox_options.add_argument('--headless')
driver = webdriver.Firefox(firefox_options=firefox_options)
一样是在 Webdriver 初始化的时候增加 headless
参数就可以了。
好了,本篇的内容就到这里了,希望各位同学可以自己动手练习下哦~~~
小白学 Python 爬虫:Selenium 获取某大型电商网站商品信息的更多相关文章
- 小白学 Python 爬虫(29):Selenium 获取某大型电商网站商品信息
人生苦短,我用 Python 前文传送门: 小白学 Python 爬虫(1):开篇 小白学 Python 爬虫(2):前置准备(一)基本类库的安装 小白学 Python 爬虫(3):前置准备(二)Li ...
- 吴裕雄--天生自然PYTHON爬虫:使用Selenium爬取大型电商网站数据
用python爬取动态网页时,普通的requests,urllib2无法实现.例如有些网站点击下一页时,会加载新的内容,但是网页的URL却没有改变(没有传入页码相关的参数),requests.urll ...
- 小白学 Python 爬虫(40):爬虫框架 Scrapy 入门基础(七)对接 Selenium 实战
人生苦短,我用 Python 前文传送门: 小白学 Python 爬虫(1):开篇 小白学 Python 爬虫(2):前置准备(一)基本类库的安装 小白学 Python 爬虫(3):前置准备(二)Li ...
- 小白学 Python 爬虫(30):代理基础
人生苦短,我用 Python 前文传送门: 小白学 Python 爬虫(1):开篇 小白学 Python 爬虫(2):前置准备(一)基本类库的安装 小白学 Python 爬虫(3):前置准备(二)Li ...
- 小白学 Python 爬虫(31):自己构建一个简单的代理池
人生苦短,我用 Python 前文传送门: 小白学 Python 爬虫(1):开篇 小白学 Python 爬虫(2):前置准备(一)基本类库的安装 小白学 Python 爬虫(3):前置准备(二)Li ...
- 小白学 Python 爬虫(32):异步请求库 AIOHTTP 基础入门
人生苦短,我用 Python 前文传送门: 小白学 Python 爬虫(1):开篇 小白学 Python 爬虫(2):前置准备(一)基本类库的安装 小白学 Python 爬虫(3):前置准备(二)Li ...
- 小白学 Python 爬虫(33):爬虫框架 Scrapy 入门基础(一)
人生苦短,我用 Python 前文传送门: 小白学 Python 爬虫(1):开篇 小白学 Python 爬虫(2):前置准备(一)基本类库的安装 小白学 Python 爬虫(3):前置准备(二)Li ...
- 小白学 Python 爬虫(34):爬虫框架 Scrapy 入门基础(二)
人生苦短,我用 Python 前文传送门: 小白学 Python 爬虫(1):开篇 小白学 Python 爬虫(2):前置准备(一)基本类库的安装 小白学 Python 爬虫(3):前置准备(二)Li ...
- 小白学 Python 爬虫(35):爬虫框架 Scrapy 入门基础(三) Selector 选择器
人生苦短,我用 Python 前文传送门: 小白学 Python 爬虫(1):开篇 小白学 Python 爬虫(2):前置准备(一)基本类库的安装 小白学 Python 爬虫(3):前置准备(二)Li ...
随机推荐
- 欧拉降幂 (a^t)%c 模板
#include<bits/stdc++.h> using namespace std; typedef long long ll; ll a,c,p,mod; ]; ll phi(ll ...
- mtrace 简介
内存泄露问题一般会再长时间运行的程序中暴露出来.而且一般很难定位和查找. linux 提供mtrace/muntrace来检测程序是否有内存泄露.一般来说要检测哪一段代码是否有内存泄露,就可以用这一对 ...
- 【DRF版本控制】
目录 使用内置的URLPathVersioning类 使用自定义的版本控制类 "首先,我们开发的项目会有多个版本. 其次,我们的项目版本会随着更新越来越多,我们不可能因出了新版本就不维护旧版 ...
- P & R 10
作为一个后端设计者,所需要掌握的技能其实就是熟练的利用工具,为自己服务. 需要的知识是什么?说的简单点,就是如何把设计的PPA搞上去. 说的复杂点,那就得从PPA需要注意的每个点去一一剖析.这个就太需 ...
- jinja 语法 - 整型转字符串
大多数 jinja 相关的问题,其实查文档就解决了,但后来遇到这个问题,使得我把 jinja 官方文档,api.样例等,认真读了个遍= =. 发现没有直接的办法可以将整型转为字符串,对于需要进行字符串 ...
- Win10-IIS注册asp 此操作系统版本不支持此选项 错误解决方法
现象再现: 今日在Win10上面ASP.NET网站突然不能跑了, 过程再现: 根据资料提示重新注册ASPNET_IIS.exe -i 直接提示: C:\WINDOWS\system32>c:\w ...
- static关键字 weak关键字
1.static关键字 static HAL_StatusTypeDef UART_Receive_IT(UART_HandleTypeDef *huart){ ...} 在函数前面加了一个stati ...
- 新手学习arm的建议
本文来自:chen4013874的博客 如果您是ARM初学者或者以前是51单片机应用开发工程师,想快速进入32位ARM嵌入式开发领域,建议您阅读本文档.本文档是我们结合多年ARM开发经验,针对初学者对 ...
- nginx 解决 connect() failed (111: Connection refused) while connecting to upstream,
嗯哼,刚装了个ubuntu的lnmp,我的天啊,踩的坑比我脂肪还多了 比如刚装完的时候访问显示502, 也不知道什么问题,就去看了一下nginx日志 /var/log/nginx/error.log ...
- 如何利用wx.login方法获取openid和sessionKey
1, wx.login(Object object) 调用接口获取登录凭证(code).通过凭证进而换取用户登录态信息,包括用户的唯一标识(openid)及本次登录的会话密钥(session_key) ...