写在前面

之前写过一个爬取京东商品的Scrapy爬虫项目,但是里面价格及评论数是通过逆向工程法获得的,在不使用代理ip的情况下,在爬取一定数量的商品后会被持续要求输入验证码。所以这里写出利用动态页面渲染对京东商品价格及评论数爬取的方法。
在之前的项目中,构造特殊请求获得的数据有:

  1. 价格
  2. 评论数
  3. 好评度

但由于好评度需要进入单个商品的页面才能获取,而利用动态渲染页面爬取数据其实是模拟真实浏览器对网页访问,加载所有网页内容后实现“可见即可得”,所以速度比requests.get()等要慢很多很多,在要批量爬取大量商品信息时效率极低。所以这里就舍弃了好评度这项数据,保留了 价格 和 评论数 这两项在商品浏览页面就可以获取的数据。


利用Selenium对价格、评论数提取

注:这里使用谷歌浏览器

首先利用Selenium打开Chrome并访问商品页面(由于要批量爬取商品信息,所以这里使用headless模式隐藏浏览器界面):

from selenium import webdriverchrome_options = webdriver.ChromeOptions()
chrome_options.add_argument('--headless')
browser = webdriver.Chrome(chrome_options=chrome_options)page = 1
url = "https://list.jd.com/list.html?cat=670,671,672&page=" + str(page) + "&sort=sort_totalsales15_desc&trans=1&JL=6_0_0#J_main"
browser.get(url)
html = browser.page_source

这样就获取了页面所有信息,然后在Chrom的开发者工具中对页面进行分析:

可见每一个<li class="gl-item">...</li>中都包含了一个商品的信息,点开找到价格和评论数所处的位置:

然后利用pyquery库对价格和评论数进行提取:

from pyquery import PyQuery as pq
doc = pq(html)

首先提取所有的<li class="gl-item">...</li>:

info = doc('.gl-item').items()

然后遍历并提取价格和评论数:

for item in info:price = item.find('.J_price.js_ys').text()comment = item.find('.p-commit').text()

多观察几个商品后会发现有的商品评论数后有“二手有售”,而有的没有

而“二手有售”将会出现在提取的comment中,所以进行处理:

import re
comment = re.compile(r'已有\n(.*?)\n人评价').findall(comment)[0]

这样提取出来的评论为“2.3万+”这样的格式,为了后期在数据库中对数据的比较操作,这里再进行处理:

if '万' in comment:comment = comment.replace('万+', '')comment = int(float(comment) * 10000)
elif '+' in comment:comment = int(comment.replace('+', ''))

同样的,对价格进行处理:

price = float(price.replace('¥\n', ''))

最后将两个数据分别存储到对应的列表中:

prices = []
comments = []
prices.append(price)
comments.append(comment)
这样商品的价格和评论数就提取完成了。

后期操作和之前写的项目 Scrapy框架爬虫项目:京东商城笔记本电脑信息爬取 基本相同

运行图片:

代码如下:

更新:
1. 增加功能:商品爬取失败后单独存储商品链接并在后期重新爬取
2. 解决了“全球购”商品的信息存储格式与普通商品不同导致爬取失败的问题

from selenium import webdriver
from pyquery import PyQuery as pq
import pymysql
import re
import urllib.request
import time
import socket
import threadingconnection = pymysql.connect(user='root', password='Zwp0816...', host='127.0.0.1', db='JD_Goods')
cursor = connection.cursor()
cursor.execute('drop table if exists new_Goods;')
cursor.execute('create table new_Goods(名称 varchar(100), 价格 float, 评论 int, 内存 varchar(100), CPU类型 varchar(100), CPU型号 varchar(100), CPU速度 varchar(100), CPU核心 varchar(100), 硬盘容量 varchar(100), 固态硬盘 varchar(100), 显卡类型 varchar(100), 显示芯片 varchar(100), 显存容量 varchar(100), 尺寸 varchar(100), 重量 varchar(100), 链接 varchar(100));')
# cursor.execute('create table Goods(名称 varchar(100), 价格 varchar(100), 好评数 int, 差评数 int, 好评度 varchar(10), 内存 varchar(100), CPU类型 varchar(100), CPU型号 varchar(100), CPU速度 varchar(100), CPU核心 varchar(100), 硬盘容量 varchar(100), 固态硬盘 varchar(100), 显卡类型 varchar(100), 显示芯片 varchar(100), 显存容量 varchar(100), 尺寸 varchar(100), 重量 varchar(100), 链接 varchar(100));')
connection.commit()chrome_options = webdriver.ChromeOptions()
chrome_options.add_argument('--headless')
# browser2 = webdriver.Chrome(chrome_options=chrome_options)
'''
browser = webdriver.Firefox()
'''
# TOTAL为总页数
url = 'https://list.jd.com/list.html?cat=670,671,672&page=1'
TOTAL = int(re.findall('<em>共<b>(.*?)</b>', urllib.request.urlopen(url).read().decode('utf-8', 'ignore'))[0])
# print(TOTAL)
#TOTAL = 1global count, links, prices, comments, retry_index, retry_products, fail_links
count = 0
links = []
prices = []
comments = []
retry_index = []
retry_products = []
fail_links = []def get_url_price_and_comment(index):try:url = "https://list.jd.com/list.html?cat=670,671,672&page=" + str(index) + "&sort=sort_totalsales15_desc&trans=1&JL=6_0_0#J_main"page = urllib.request.urlopen(url).read().decode('gbk', 'ignore')global links, prices, commentsresults = re.compile('<a target="_blank" title="" href="(.*?)">').findall(page)for i in range(0, len(results)):results[i] = 'https:' + results[i]links += resultsbrowser = webdriver.Chrome(chrome_options=chrome_options)browser.get(url)html = browser.page_sourcedoc = pq(html)browser.close()info = doc('.gl-item').items()for item in info:price = item.find('.J_price.js_ys').text()try:price = float(price.replace('¥\n', ''))except:price = "NULL"prices.append(price)comment = item.find('.p-commit').text()comment = re.compile(r'已有\n(.*?)\n人评价').findall(comment)[0]if '万' in comment:comment = comment.replace('万+', '')comment = int(float(comment) * 10000)elif '+' in comment:comment = int(comment.replace('+', ''))comments.append(comment)print("\n======================第" + str(index) + "页======================\n")except Exception as e:print(e)global retry_indexretry_index.append(index)def get_product(page):global links, prices, commentslink = links.pop(0)price = prices.pop(0)comment = comments.pop(0)try:html = urllib.request.urlopen(link, timeout=5).read().decode('gbk', 'ignore')name = re.compile('<img id="spec-img".*?alt="(.*?)"', re.S).findall(html)[0]name = name.strip()result1 = re.compile('<dt>内存容量</dt>.*?<dd>(.*?)<', re.S).findall(html)result2 = re.compile('<dt>内存类型</dt>.*?<dd>(.*?)<', re.S).findall(html)result1 = result1[0] if result1 != [] else ''result2 = result2[0] if result2 != [] else ''internalStorage = result1 + result2# print(internalStorage)result = re.compile('<dt>CPU类型</dt>.*?<dd>(.*?)<', re.S).findall(html)cpu_type = result[0] if result != [] else ''# print(cpu_type)result = re.compile('<dt>CPU型号</dt>.*?<dd>(.*?)<', re.S).findall(html)cpu_Mode = result[0] if result != [] else ''# print(cpu_Mode)result = re.compile('<dt>CPU速度</dt>.*?<dd>(.*?)<', re.S).findall(html)cpu_speed = result[0] if result != [] else ''result = re.compile('<dt>核心</dt>.*?<dd>(.*?)<', re.S).findall(html)cpu_core = result[0] if result != [] else ''result = re.compile('<dt>硬盘容量</dt>.*?<dd>(.*?)<', re.S).findall(html)diskCapacity = result[0] if result != [] else ''result = re.compile('<dt>固态硬盘</dt>.*?<dd>(.*?)<', re.S).findall(html)SSD = result[0] if result != [] else ''result = re.compile('<dt>类型</dt>.*?<dd>(.*?)<', re.S).findall(html)GCtype = result[0] if result != [] else ''result = re.compile('<dt>显示芯片</dt>.*?<dd>(.*?)<', re.S).findall(html)GCcore = result[0] if result != [] else ''result = re.compile('<dt>显存容量</dt>.*?<dd>(.*?)<', re.S).findall(html)GCcapacity = result[0] if result != [] else ''result = re.compile('<dt>尺寸</dt>.*?<dd>(.*?)<', re.S).findall(html)size = result[0] if result != [] else ''result = re.compile('<dt>净重</dt>.*?<dd>(.*?)<', re.S).findall(html)weight = result[0] if result != [] else ''if price != 'NULL':sql = 'insert into new_Goods values(%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)'cursor.execute(sql, (name, price, comment, internalStorage, cpu_type, cpu_Mode, cpu_speed, cpu_core, diskCapacity, SSD,GCtype,GCcore, GCcapacity, size, weight, link))connection.commit()global countcount += 1print("第" + str(page) + "页\t\t总第" + str(count) + "个商品处理完成\t\t完成度:" + str(int((count / (TOTAL * 60)) * 1000000) / 10000) + "%")else:global retry_productsinfo = {'link': link, 'comment': comment}retry_products.append(info)print('! ! ! ! ! !错误: 价格为空\t稍后重试')except Exception as e:print('! ! ! ! ! !错误: ', e, '\t稍后重试')info = {'link': link, 'comment': comment}retry_products.append(info)def retry_product(page):global retry_productsinfo = retry_products.pop(0)link = info['link']comment = info['comment']try:browser = webdriver.Chrome(chrome_options=chrome_options)browser.get(link)doc = pq(browser.page_source)price = doc.find('.summary-price .price').text()price = float(price)html = urllib.request.urlopen(link, timeout=None).read().decode('gbk', 'ignore')name = re.compile('<img id="spec-img".*?alt="(.*?)"', re.S).findall(html)[0]name = name.strip()result1 = re.compile('<dt>内存容量</dt>.*?<dd>(.*?)<', re.S).findall(html)result2 = re.compile('<dt>内存类型</dt>.*?<dd>(.*?)<', re.S).findall(html)result1 = result1[0] if result1 != [] else ''result2 = result2[0] if result2 != [] else ''internalStorage = result1 + result2# print(internalStorage)result = re.compile('<dt>CPU类型</dt>.*?<dd>(.*?)<', re.S).findall(html)cpu_type = result[0] if result != [] else ''# print(cpu_type)result = re.compile('<dt>CPU型号</dt>.*?<dd>(.*?)<', re.S).findall(html)cpu_Mode = result[0] if result != [] else ''# print(cpu_Mode)result = re.compile('<dt>CPU速度</dt>.*?<dd>(.*?)<', re.S).findall(html)cpu_speed = result[0] if result != [] else ''result = re.compile('<dt>核心</dt>.*?<dd>(.*?)<', re.S).findall(html)cpu_core = result[0] if result != [] else ''result = re.compile('<dt>硬盘容量</dt>.*?<dd>(.*?)<', re.S).findall(html)diskCapacity = result[0] if result != [] else ''result = re.compile('<dt>固态硬盘</dt>.*?<dd>(.*?)<', re.S).findall(html)SSD = result[0] if result != [] else ''result = re.compile('<dt>类型</dt>.*?<dd>(.*?)<', re.S).findall(html)GCtype = result[0] if result != [] else ''result = re.compile('<dt>显示芯片</dt>.*?<dd>(.*?)<', re.S).findall(html)GCcore = result[0] if result != [] else ''result = re.compile('<dt>显存容量</dt>.*?<dd>(.*?)<', re.S).findall(html)GCcapacity = result[0] if result != [] else ''result = re.compile('<dt>尺寸</dt>.*?<dd>(.*?)<', re.S).findall(html)size = result[0] if result != [] else ''result = re.compile('<dt>净重</dt>.*?<dd>(.*?)<', re.S).findall(html)weight = result[0] if result != [] else ''sql = 'insert into new_Goods values(%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)'cursor.execute(sql, (name, price, comment, internalStorage, cpu_type, cpu_Mode, cpu_speed, cpu_core, diskCapacity, SSD,GCtype,GCcore, GCcapacity, size, weight, link))connection.commit()global countcount += 1print("第" + str(page) + "页\t\t总第" + str(count) + "个商品处理完成\t\t完成度:" + str(int((count / (TOTAL * 60)) * 10000) / 100) + "%")except:try:# 处理“全球购”商品browser = webdriver.Chrome(chrome_options=chrome_options)browser.get(link)doc = pq(browser.page_source)price = doc.find('.p-price .price').html()price = float(price)html = urllib.request.urlopen(link, timeout=None).read().decode('gbk', 'ignore')name = doc.find('.sku-name').text()name = name.replace('"', '')name = name.strip()result1 = re.compile('<td class="tdTitle">最大支持容量.*?<td>(.*?)<', re.S).findall(html)result2 = re.compile('<td class="tdTitle">内存类型.*?<td>(.*?)<', re.S).findall(html)result1 = "最大支持容量" + result1[0] if result1 != [] else ''result2 = result2[0] if result2 != [] else ''internalStorage = result2 + ' ' + result1# print(internalStorage)result = re.compile('<td class="tdTitle">CPU类型</td>.*?<td>(.*?)<', re.S).findall(html)cpu_type = result[0] if result != [] else ''# print(cpu_type)result = re.compile('<tr><td class="tdTitle">CPU型号</td>.*?<td>(.*?)<', re.S).findall(html)cpu_Mode = result[0] if result != [] else ''# print(cpu_Mode)result = re.compile('<tr><td class="tdTitle">CPU速度</td>.*?<td>(.*?)<', re.S).findall(html)cpu_speed = result[0] if result != [] else ''result = re.compile('<td class="tdTitle">核心</td>.*?<td>(.*?)<', re.S).findall(html)cpu_core = result[0] if result != [] else ''result = re.compile('<td class="tdTitle">硬盘容量</td>.*?<td>(.*?)<', re.S).findall(html)diskCapacity = result[0] if result != [] else ''result = re.compile('<td class="tdTitle">固态硬盘</td>.*?<td>(.*?)<', re.S).findall(html)SSD = result[0] if result != [] else ''result = re.compile('<td class="tdTitle">类型</td>.*?<td>(.*?)<', re.S).findall(html)GCtype = result[0] if result != [] else ''result = re.compile('<td class="tdTitle">显示芯片</td>.*?<td>(.*?)<', re.S).findall(html)GCcore = result[0] if result != [] else ''result = re.compile('<td class="tdTitle">显存容量</td>.*?<td>(.*?)<', re.S).findall(html)GCcapacity = result[0] if result != [] else ''result = re.compile('<td class="tdTitle">屏幕尺寸</td>.*?<td>(.*?)<', re.S).findall(html)size = result[0] if result != [] else ''result = re.compile('<td class="tdTitle">净重</td>.*?<td>(.*?)<', re.S).findall(html)weight = result[0] if result != [] else ''sql = 'insert into new_Goods values(%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)'cursor.execute(sql, (name, price, comment, internalStorage, cpu_type, cpu_Mode, cpu_speed, cpu_core, diskCapacity, SSD,GCtype,GCcore, GCcapacity, size, weight, link))connection.commit()count += 1print("第" + str(page) + "页\t\t总第" + str(count) + "个商品处理完成\t\t完成度:" + str(int((count / (TOTAL * 60)) * 10000) / 100) + "%")except:print("* * * * * 商品信息无法处理,链接:", link)global fail_linksfail_links.append(link)def main():print("\n开始处理商品...")start = 1end = start + TOTALfor i in range(start, end):get_url_price_and_comment(i)while links != []:get_product(i)if retry_products != []:print("\t--------正在重新处理错误商品--------")while retry_products != []:retry_product(i)print("\n第" + str(i) + "页处理完成")while retry_index != []:index = retry_index.pop(0)get_url_price_and_comment(index)if retry_products != []:print("\t--------正在重新处理错误商品--------")while retry_products != []:retry_product(i)print("\n第" + str(index) + "页处理完成")print("**************所有商品链接处理完成**************")if __name__ == '__main__':main()

利用动态渲染页面对京东笔记本电脑信息爬取相关推荐

  1. Scrapy框架爬虫项目:京东商城笔记本电脑信息爬取

    一.创建Scrapy项目 在cmd中输入一下指令创建一个新的scrapy项目及一个爬虫 scrapy startproject JD_Goodscd JD_Goodsscrapy genspider ...

  2. webscraper多页爬取_爬虫工具实战篇(Web Scraper)- 京东商品信息爬取(原创)

    一.背景与目的 数字化营销时代,快速掌握了解数据是一项基本技能,本文主要讲解里面Web Scraper工具如何爬取公开数据,比如爬取京东的店铺售卖商品情况数据,以便我们更好地了解竞品对手的产品情况和定 ...

  3. 案例总结:京东图书信息爬取

    代码地址:https://github.com/Fonzie9527/spider_JDbooks 爬取起始url:https://book.jd.com/booksort.html 爬取需求:抓取京 ...

  4. 爬虫数据存储到数据库/增量爬虫+多级页面获取=====安居客信息爬取

    文章目录 前言 一.增量爬虫是什么? 二.python数据存储到数据库 三.多级页面的跳转获取 四:遇到的问题以及解决 五:代码 总结 前言:这次的爬取内容是安居客网页里面的信息,首先是我爬取的页面是 ...

  5. 京东爬虫——京东评论信息爬取及评论图片的下载

    之前,我做了一个天猫评论信息的抓取,和评论图片的下载,不过那次是将信息全部存入数据库后再从数据库提取图片信息进行下载,这次我做了一个信息抓取和图片下载的二合一升级版. 本次以京东nike自营店为目标, ...

  6. scrapy模拟浏览器爬取51job(动态渲染页面爬取)

    scrapy模拟浏览器爬取51job 51job链接 网络爬虫时,网页不止有静态页面还有动态页面,动态页面主要由JavaScript动态渲染,网络爬虫经常遇见爬取JavaScript动态渲染的页面. ...

  7. python爬虫 京东,苏宁,小米众筹网站信息爬取

    可代写python爬虫,收费可协商,用途需提前说明. 下面爬虫爬到的数据有100天左右,100家众筹的完整数据,需要的或者有写爬虫需求的同学可发邮件至starinsunriseabovesea@ali ...

  8. Python3网络爬虫实战-38、动态渲染页面抓取:Splash的使用

    Splash 是一个 JavaScript 渲染服务,是一个带有 HTTP API 的轻量级浏览器,同时它对接了 Python 中的 Twisted和 QT 库,利用它我们同样可以实现动态渲染页面的抓 ...

  9. Python爬虫基础(三) —— 爬取动态渲染页面

    文章目录 使用Selenium库 例子引入 声明游览器对象 访问页面 查找节点 单个节点 多个节点 节点交互 动作链 模拟执行javascript 获取节点信息 获取属性 获取文本值 获取id,位置, ...

最新文章

  1. C#实现在Winform中嵌入Word和Excel
  2. mysql 语句优化实例_MySQL 语句优化实例
  3. 近似与精确——《狂人C》习题解答15(第三章习题5)
  4. 声明式事务控制的实现
  5. 在Windows Server 2012中配置NAT代理服务器
  6. 微信支付现金红包接口(转)
  7. Python和SQL Server 2017的力量
  8. HDU5923-Prediction-有继承味道的并查集
  9. 数码管显示实验一 编写程序让8只数码管同时显示零
  10. (27)FPGA计数器设计(硬核实现)
  11. 这可能是国内首款5G手机了!中兴AXON 10 Pro 5G上市定档
  12. 2018.3.10 模拟赛——(2)给出字符串
  13. HDU 4387 Stone Game (博弈)
  14. 关于openstack,cloudstack,Eucalyptus对比分析
  15. 2021机器学习面试必考100题最新汇总(附答案详解)
  16. 戴顿大学计算机科学,(出国) 2015年 清北 上海交大浙大复旦中科南大 世界TOP30高校 官方数据...
  17. 鲁卡斯队列求黄金分割数
  18. 探索的动机: 爱因斯坦于1918年4月的讲话
  19. 工业机器人调运角度_工业机器人的应用案例
  20. Python 基于csv 读取文本文件提示:‘gbk‘ codec can‘t decode byte 0xbf in position 2: illegal multibyte sequence

热门文章

  1. 黑盒测试用例设计--题目3
  2. 双电阻差分电流采样_1206 0.35R采样毫欧电阻等规格参数应用详情
  3. 陆奇,59岁,创业者:真正的高手,都是时间的长期主义者!
  4. 西北农林科技大学接口技术设计性实验一——8255并行接口实验
  5. 代码量?项目经验?面试官你到底要看程序员哪一点
  6. Reso | Noise 网易云音乐插件
  7. 技术面试遇到不会的问题怎么办?教你3招技巧!
  8. android 黑科技 hook技术简单示例
  9. freebsd java 能用吗_FreeBSD6.2 java web环境搭建
  10. DynamicDto链式实现动态数据传输对象