学习中...【京东价格/评论数据】数据获取方式——采用Selenium★

近期闲来无事学学selenium爬虫技术,参考崔庆才《Python3网络爬虫开发实战》的淘宝商品信息爬取,我也照猫画虎的学了京东的价格和商品评论数据。废话不多说,直接开始吧!

1. 浏览器初始化

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.wait import WebDriverWait
from selenium.common.exceptions import TimeoutException
from selenium.webdriver.chrome.options import Options
from bs4 import BeautifulSoup
import time
import reoptions = Options()
options.add_argument('--headless')  #使用无头浏览器(PhantomJS已经不支持了)
browser = webdriver.Chrome(options = options)
browser.maximize_window()  
wait = WebDriverWait(browser, 10)

注意这里的browser.maximize_window()非常重要,否则京东自己的弹窗会屏蔽掉网页自身的按钮。

2. 商品页搜索

这里我用的搜索页是京东商品搜索,页面比较简洁。

在Chrome浏览器中右键检查后可以看到

搜索商品输入框(黑框)的id是keyword

搜索商品确认框(蓝框)的class是input_submit,于是我写了如下代码

def search(keyword):browser.get("https://search.jd.com/")input_ = wait.until(EC.presence_of_element_located((By.ID, 'keyword')))submit = wait.until(EC.element_to_be_clickable((By.CLASS_NAME, "input_submit")))input_.clear() input_.send_keys(keyword)submit.click()

由于最近肺炎比较严重,我们keyword不妨设为口罩,submit过后,我们就会来到商品页。我们先判断口罩商品一共有多少页

可以看到一共有100页,不过在滑动的过程中我们发现网页是不断加载出来的,所以我们代码也得进行滑动到最底端这个操作,现在我们先观察如何获得100这个数字。

事实上他就是class为p-skip的span元素下属的b元素的文本而已。综上我给出搜索商品及获得页数这块的整体代码

def search(keyword):browser.get("https://search.jd.com/")input_ = wait.until(EC.presence_of_element_located((By.ID, 'keyword')))submit = wait.until(EC.element_to_be_clickable((By.CLASS_NAME, "input_submit")))input_.clear()input_.send_keys(keyword)submit.click()print("Success")# 滑到最底端browser.execute_script('window.scrollTo(0, document.body.scrollHeight)')# 总页数number = wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, '.p-skip b'))).textreturn number

3. 获得每个商品链接

我们观察商品链接处的源代码(红框处)

可以发现他们是属于.gl-item的li元素下的.p-name的div元素(.表示class),并且target为_blank,于是我们可以这样访问

wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, '.gl-item .p-name [target=_blank]')))
url_list = browser.find_elements_by_css_selector(".gl-item .p-name [target=_blank]")
for url in url_list:link_list.append(url.get_attribute("href") + "#comment") # 加上#comment是因为这是评论页的后缀

那么link_list里面就包含了我们所有需要的link信息(说明一下,webelement用get_attribute获得href比用bs4解析要好,他会自动补全上级链接信息。如果直接用bs4解析网址,可能你得到的网址没有加"https"

接下来我们要进行换页,同样是下拉到最底端

橙框是输入页数框,可以看到他是p-skip下input-text,绿框是确认框,他是p-skip下btn。同时input-text也显示目前所在页数,可以作为我们的翻页是否成功的检验,我们有如下代码。

def change_page(page):print("正在爬第", page, "页")browser.execute_script('window.scrollTo(0, document.body.scrollHeight)')time.sleep(3)page_box = wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, '.p-skip input')))page_box.clear()page_box.send_keys(str(page))submit = wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, '.p-skip .btn')))submit.click()# 检查是否加载成功wait.until(EC.text_to_be_present_in_element_value((By.CSS_SELECTOR, '.p-skip input'), str(page)))

在滑到最下面用time.sleep强制休息一下,不然输入框可能加载不出来(估计京东有反爬措施)。并且每次运行完change_page获得商品链接的时候也sleep加载一下

4. 爬取评论

下面就是最难的爬评论了,京东的限制还是比较多的。

打开评论页发现评论的结构还是蛮简单的,每个评论就是#comment下.comments-list的[data-tab=item],评论文字就是.comment-con的text。对于评论的提取我们不再用webelement的find方式,因为容易出现stale element错误(加载太慢),转而使用bs4的select函数。

换页的定位也不难,不过下一页按钮容易被小图标遮挡,我们用browser.execute_script("arguments[0].click();", next_page) 解决问题。值得注意的是,如果换页太快容易被京东检测到,所以我们爬取一会儿休息一下。

def get_comment(link):product_id = re.search("https://item.jd.com/(\d+).html#comment", link).group(1)browser.get(link)count = 0file = open("JD_%s_comments.txt"%product_id, "a", encoding='utf-8')while True:try:if count%10 == 0:time.sleep(3)browser.execute_script('window.scrollTo(0, document.body.scrollHeight)')wait.until(EC.presence_of_element_located((By.CSS_SELECTOR,"#comment .comments-list [data-tab=item] .comment-con")))soup = BeautifulSoup(browser.page_source, 'lxml')url_list = soup.select("#comment .comments-list [data-tab=item] .comment-con")for url in url_list:file.write(url.text.strip()+"\n")count += 1next_page = wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, "#comment .ui-page .ui-pager-next")))browser.execute_script("arguments[0].click();", next_page) # 被图标遮挡了except TimeoutException:print("已爬取", count, "页评论")file.close()break

最后我们整合一下完整代码,爬取就完成了

"""
Created on Mon Feb  3 21:01:53 2020@author: Simon
"""from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.wait import WebDriverWait
from selenium.common.exceptions import TimeoutException
from selenium.webdriver.chrome.options import Options
from bs4 import BeautifulSoup
import time
import reoptions = Options()
options.add_argument('--headless')
browser = webdriver.Chrome(options = options)
browser.maximize_window()
wait = WebDriverWait(browser, 10)
def search(keyword):browser.get("https://search.jd.com/")input_ = wait.until(EC.presence_of_element_located((By.ID, 'keyword')))submit = wait.until(EC.element_to_be_clickable((By.CLASS_NAME, "input_submit")))input_.clear()input_.send_keys(keyword)submit.click()print("Success")# 滑到最底端browser.execute_script('window.scrollTo(0, document.body.scrollHeight)')# 总页数number = wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, '.p-skip b'))).textreturn numberdef change_page(page):print("正在爬第", page, "页")browser.execute_script('window.scrollTo(0, document.body.scrollHeight)')time.sleep(3)page_box = wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, '.p-skip input')))page_box.clear()page_box.send_keys(str(page))submit = wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR, '.p-skip .btn')))submit.click()# 检查是否加载成功wait.until(EC.text_to_be_present_in_element_value((By.CSS_SELECTOR, '.p-skip input'), str(page)))def get_comment(link):product_id = re.search("https://item.jd.com/(\d+).html#comment", link).group(1)browser.get(link)count = 0file = open("JD_%s_comments.txt"%product_id, "a", encoding='utf-8')while True:try:if count%10 == 0:time.sleep(3)browser.execute_script('window.scrollTo(0, document.body.scrollHeight)')wait.until(EC.presence_of_element_located((By.CSS_SELECTOR,"#comment .comments-list [data-tab=item] .comment-con")))soup = BeautifulSoup(browser.page_source, 'lxml')url_list = soup.select("#comment .comments-list [data-tab=item] .comment-con")for url in url_list:file.write(url.text.strip()+"\n")count += 1next_page = wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, "#comment .ui-page .ui-pager-next")))browser.execute_script("arguments[0].click();", next_page) # 被图标遮挡了except TimeoutException:print("已爬取", count, "页评论")file.close()breakif __name__ == '__main__':number = search("口罩")link_list = []for page in range(1, int(number) + 1):change_page(page)time.sleep(3)wait.until(EC.presence_of_element_located((By.CSS_SELECTOR, '.gl-item .p-name [target=_blank]')))url_list = browser.find_elements_by_css_selector(".gl-item .p-name [target=_blank]")for url in url_list:link_list.append(url.get_attribute("href") + "#comment")for link in link_list:get_comment(link)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/web/12495.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

红黑树的平衡

1.红黑树的概念 红黑树,是一种二叉搜索树,但在每个结点上增加一个存储位表示结点的颜色,可以是Red或 Black。 通过对任何一条从根到叶子的路径上各个结点着色方式的限制,红黑树确保没有一条路 径会比其他路径长出俩倍&#xff0c…

合合信息:TextIn文档解析技术与高精度文本向量化模型再加速

文章目录 前言现有大模型文档解析问题表格无法解析无法按照阅读顺序解析文档编码错误 诉求文档解析技术技术难点技术架构关键技术回根溯源 文本向量化模型结语 前言 随着人工智能技术的持续演进,大语言模型在我们日常生活中正逐渐占据举足轻重的地位。大模型语言通…

Scala基础

目录 1.安装与运行Scala 任务描述 了解Scala语言 了解Scala特性 安装Scala 运行Scala 2.定义函数识别号码类型 了解数据类型 定义与使用常量、变量 使用运算符 定义与使用数组 任务实现 3.基本语法 1 变量 2 字符串 3 数据类型&操作符 4 条件表达式 5 循环…

idea使用gitee基本操作流程

1.首先,每次要写代码前,先切换到自己负责的分支 点击签出。 然后拉取一次远程master分支,保证得到的是最新的代码。 写完代码后,在左侧栏有提交按钮。 点击后,选择更新的文件,输入描述内容(必填…

五分钟“手撕”时间复杂度与空间复杂度

目录 一、算法效率 什么是算法 如何衡量一个算法的好坏 算法效率 二、时间复杂度 时间复杂度的概念 大O的渐进表示法 推导大O阶方法 常见时间复杂度计算举例 三、空间复杂度 常见时间复杂度计算举例 一、算法效率 什么是算法 算法(Algorithm):就是定…

C++|多态性与虚函数(2)|虚析构函数|重载函数|纯虚函数|抽象类

前言 看这篇之前,可以先看多态性与虚函数(1)⬇️ C|多态性与虚函数(1)功能绑定|向上转换类型|虚函数-CSDN博客https://blog.csdn.net/weixin_74197067/article/details/138861418?spm1001.2014.3001.5501这篇文章会…

【十大排序算法】----C语言版插入排序(详细图解)

目录 一:插入排序——原理 二:插入排序——分析 三:插入排序——实现 四:插入排序——效率 一:插入排序——原理 插入排序的原理和基本思想:把待排序的记录按其关键码值的大小逐个插入到一个已经排好序…

Django使用

一、根目录下安装 pip install django 二、创建djiango项目 django-admin startproject 项目名称 三、创建app python manage.py startapp app名称 四、启动 python manage.py runserver 五、编写URL与视图关系,相对路径 1、manage.py(见资源绑定…

多元化、高辨识显示丨基于G32A1445的汽车尾灯解决方案

由刹车灯、倒车灯、转向灯、雾灯等组成的汽车尾灯,既能在光线低暗时发出照明信息,也可向周围环境传递车辆的行驶状态与意图信号,对于行车安全起着至关重要的作用。与传统尾灯相比,贯穿式汽车尾灯更加醒目、美观、安全,…

CSS2(一):CSS选择器

文章目录 1、CSS基础1.1 CSS简介1.2 CSS编写位置1.2.1 行内样式1.2.2 内部样式1.2.3 外部样式1.2.4 样式优先级 1.2.5 CSS代码风格 2、CSS选择器2.1、基本选择器2.1.1 通配选择器2.1.2 元素选择器2.1.3 类选择器2.1.4 ID选择器2.1.5 总结 2.2、CSS复合选择器2.2.1 交集选择器2.…

海外媒体宣发:新加坡.马来西亚如何在海外媒体投放新闻通稿-大舍传媒

导言 随着全球化的进程加速,海外市场对于企业的发展越来越重要。而在海外媒体上宣传企业的新闻通稿,成为了拓展海外市场和提升企业知名度的重要手段之一。本文将介绍大舍传媒对于如何在海外媒体上投放新闻通稿的经验和策略。 准备工作:了解…

Hive 特殊的数据类型 Array、Map、Struct

Array 数组类型,存储数据类型一致的列表数据。 我们可以使用 array 方法来创建一个数组,如下所示: select array(1,2,3,4,5);如果其中的数据类型不一致,那么它会转换成统一的数据类型(前提是能够进行转换&#xff0…

力扣HOT100 - 322. 零钱兑换

解题思路&#xff1a; 动态规划 class Solution {public int coinChange(int[] coins, int amount) {int[] dp new int[amount 1];Arrays.fill(dp, amount 1);dp[0] 0;for (int i 1; i < amount; i) {for (int j 0; j < coins.length; j) {if (coins[j] < i) …

宠物管理系统带万字文档

文章目录 宠物管理系统一、项目演示二、项目介绍三、19000字论文参考四、部分功能截图五、部分代码展示六、底部获取项目源码和万字论文参考&#xff08;9.9&#xffe5;带走&#xff09; 宠物管理系统 一、项目演示 宠物管理系统 二、项目介绍 基于springbootvue的前后端分离…

新串口通道打通纪实

在计算机系统中&#xff0c;串口是“古老”的通信方式&#xff0c;和它同时代的“并口”通信方式已经消失了。但它仍然顽强的存活着&#xff0c;主要原因是在开发和调试底层软件时还经常用到串口。 正因为有这样的需求&#xff0c;幽兰代码本是支持串口的&#xff0c;而且有两种…

【现代C++】概念的使用

现代C&#xff08;特别是C20及以后的版本&#xff09;引入了概念&#xff08;Concepts&#xff09;&#xff0c;这是一种指定模板参数必须满足的约束的方式。概念使得模板代码更清晰&#xff0c;更容易理解和使用&#xff0c;并且能在编译时提供更好的错误信息。以下是C概念的关…

UStaticMesh几何数据相关(UE5.2)

UStaticMesh相关类图 UStaticMesh的数据构成 UStaticMesh的FStaticMeshSourceModel UStaticMesh的Mesh几何元数据来自于FStaticMeshSourceModel&#xff0c; 一级Lod就存在一个FStaticMeshSourceModel. FStaticMeshSourceModel几何数据大致包含以下几类: Vertex(点), VertexI…

玩转Matlab-Simscape(初级)- 06 - 基于Solidworks、Matlab Simulink、COMSOL的协同仿真(理论部分2)

** 玩转Matlab-Simscape&#xff08;初级&#xff09;- 06 - 基于Solidworks、Matlab Simulink、COMSOL的协同仿真&#xff08;理论部分2&#xff09; ** 目录 玩转Matlab-Simscape&#xff08;初级&#xff09;- 06 - 基于Solidworks、Matlab Simulink、COMSOL的协同仿真&am…

风电功率预测 | 基于GRU门控循环单元的风电功率预测(附matlab完整源码)

风电功率预测 风电功率预测 | 基于GRU门控循环单元的风电功率预测(附matlab完整源码)完整代码风电功率预测 | 基于GRU门控循环单元的风电功率预测(附matlab完整源码) 完整代码 clc; clear close allX = xlsread(风电场预测.xlsx)