这篇文章,我们将通过 selenium 模拟用户使用浏览器的行为,爬取京东商品信息,还是先放上最终的效果图:

1、网页分析

(1)初步分析

原本博主打算写一个能够爬取所有商品信息的爬虫,可是在分析过程中发现,不同商品的网页结构竟然是不一样的

所以,后来就放弃了这个想法,转为只爬取笔记本类型商品的信息

如果需要爬取其它类型的商品信息,只需把提取数据的规则改变一下就好,有兴趣的朋友可以自己试试看呀

好了,下面我们正式开始!

首先,用 Chrome 浏览器打开 笔记本商品首页,我们很容易发现该网页是一个 动态加载 的网页

因为刚打开网页时只会显示 30 个商品的信息,可是当我们向下拖动网页时,它会再次加载剩下 30 个商品的信息

这时候我们可以通过 selenium 模拟浏览器下拉网页的过程,获取网站全部商品的信息

>>> browser.execute_script("window.scrollTo(0,document.body.scrollHeight)")

(2)模拟翻页

另外,我们发现该网站一共有 100 个网页

我们可以通过构造 URL 来获取每一个网页的内容,但是这里我们还是选择使用 selenium 模拟浏览器的翻页行为

下拉网页至底部可以发现有一个 下一页 的按钮,我们只需获取并点击该元素即可实现翻页

>>> browser.find_element_by_xpath('//a[@class="pn-next" and @onclick]').click()

(3)获取数据

接下来,我们需要解析每一个网页来获取我们需要的数据,具体包括(可以使用 selenium 选择元素):

  • 商品 ID:browser.find_elements_by_xpath('//li[@data-sku]') ,用于构造链接地址
  • 商品价格:browser.find_elements_by_xpath('//div[@class="gl-i-wrap"]/div[2]/strong/i')
  • 商品名称:browser.find_elements_by_xpath('//div[@class="gl-i-wrap"]/div[3]/a/em')
  • 评论人数:browser.find_elements_by_xpath('//div[@class="gl-i-wrap"]/div[4]/strong')

2、编码实现

好了,分析过程很简单,基本思路是使用 selenium 模拟浏览器的行为,下面是代码实现

from selenium import webdriver
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
import selenium.common.exceptions
import json
import csv
import time class JdSpider():
def open_file(self):
self.fm = input('请输入文件保存格式(txt、json、csv):')
while self.fm!='txt' and self.fm!='json' and self.fm!='csv':
self.fm = input('输入错误,请重新输入文件保存格式(txt、json、csv):')
if self.fm=='txt' :
self.fd = open('Jd.txt','w',encoding='utf-8')
elif self.fm=='json' :
self.fd = open('Jd.json','w',encoding='utf-8')
elif self.fm=='csv' :
self.fd = open('Jd.csv','w',encoding='utf-8',newline='') def open_browser(self):
self.browser = webdriver.Chrome()
self.browser.implicitly_wait(10)
self.wait = WebDriverWait(self.browser,10) def init_variable(self):
self.data = zip()
self.isLast = False def parse_page(self):
try:
skus = self.wait.until(EC.presence_of_all_elements_located((By.XPATH,'//li[@class="gl-item"]')))
skus = [item.get_attribute('data-sku') for item in skus]
links = ['https://item.jd.com/{sku}.html'.format(sku=item) for item in skus]
prices = self.wait.until(EC.presence_of_all_elements_located((By.XPATH,'//div[@class="gl-i-wrap"]/div[2]/strong/i')))
prices = [item.text for item in prices]
names = self.wait.until(EC.presence_of_all_elements_located((By.XPATH,'//div[@class="gl-i-wrap"]/div[3]/a/em')))
names = [item.text for item in names]
comments = self.wait.until(EC.presence_of_all_elements_located((By.XPATH,'//div[@class="gl-i-wrap"]/div[4]/strong')))
comments = [item.text for item in comments]
self.data = zip(links,prices,names,comments)
except selenium.common.exceptions.TimeoutException:
print('parse_page: TimeoutException')
self.parse_page()
except selenium.common.exceptions.StaleElementReferenceException:
print('parse_page: StaleElementReferenceException')
self.browser.refresh() def turn_page(self):
try:
self.wait.until(EC.element_to_be_clickable((By.XPATH,'//a[@class="pn-next"]'))).click()
time.sleep(1)
self.browser.execute_script("window.scrollTo(0,document.body.scrollHeight)")
time.sleep(2)
except selenium.common.exceptions.NoSuchElementException:
self.isLast = True
except selenium.common.exceptions.TimeoutException:
print('turn_page: TimeoutException')
self.turn_page()
except selenium.common.exceptions.StaleElementReferenceException:
print('turn_page: StaleElementReferenceException')
self.browser.refresh() def write_to_file(self):
if self.fm == 'txt':
for item in self.data:
self.fd.write('----------------------------------------\n')
self.fd.write('link:' + str(item[0]) + '\n')
self.fd.write('price:' + str(item[1]) + '\n')
self.fd.write('name:' + str(item[2]) + '\n')
self.fd.write('comment:' + str(item[3]) + '\n')
if self.fm == 'json':
temp = ('link','price','name','comment')
for item in self.data:
json.dump(dict(zip(temp,item)),self.fd,ensure_ascii=False)
if self.fm == 'csv':
writer = csv.writer(self.fd)
for item in self.data:
writer.writerow(item) def close_file(self):
self.fd.close() def close_browser(self):
self.browser.quit() def crawl(self):
self.open_file()
self.open_browser()
self.init_variable()
print('开始爬取')
self.browser.get('https://search.jd.com/Search?keyword=%E7%AC%94%E8%AE%B0%E6%9C%AC&enc=utf-8')
time.sleep(1)
self.browser.execute_script("window.scrollTo(0,document.body.scrollHeight)")
time.sleep(2)
count = 0
while not self.isLast:
count += 1
print('正在爬取第 ' + str(count) + ' 页......')
self.parse_page()
self.write_to_file()
self.turn_page()
self.close_file()
self.close_browser()
print('结束爬取') if __name__ == '__main__':
spider = JdSpider()
spider.crawl()

代码中有几个需要注意的地方,现在记录下来便于以后学习:

1、self.fd = open('Jd.csv','w',encoding='utf-8',newline='')

在打开 csv 文件时,最好加上参数 newline='' ,否则我们写入的文件会出现空行,不利于后续的数据处理

2、self.browser.execute_script("window.scrollTo(0,document.body.scrollHeight)")

在模拟浏览器向下拖动网页时,由于数据更新不及时,所以经常出现 StaleElementReferenceException 异常

一般来说有两种处理方法:

  • 在完成操作后使用 time.sleep() 给浏览器充足的加载时间
  • 捕获该异常进行相应的处理

3、skus = [item.get_attribute('data-sku') for item in skus]

在 selenium 中使用 xpath 语法选取元素时,无法直接获取节点的属性值,而需要使用 get_attribute() 方法

4、无头启动浏览器可以加快爬取速度,只需在启动浏览器时设置无头参数即可

opt = webdriver.chrome.options.Options()
opt.set_headless()
browser = webdriver.Chrome(chrome_options=opt)

【爬虫系列相关文章】

爬虫系列(十三) 用selenium爬取京东商品的更多相关文章

  1. selenium模块使用详解、打码平台使用、xpath使用、使用selenium爬取京东商品信息、scrapy框架介绍与安装

    今日内容概要 selenium的使用 打码平台使用 xpath使用 爬取京东商品信息 scrapy 介绍和安装 内容详细 1.selenium模块的使用 # 之前咱们学requests,可以发送htt ...

  2. 利用selenium爬取京东商品信息存放到mongodb

    利用selenium爬取京东商城的商品信息思路: 1.首先进入京东的搜索页面,分析搜索页面信息可以得到路由结构 2.根据页面信息可以看到京东在搜索页面使用了懒加载,所以为了解决这个问题,使用递归.等待 ...

  3. 爬虫(十七):Scrapy框架(四) 对接selenium爬取京东商品数据

    1. Scrapy对接Selenium Scrapy抓取页面的方式和requests库类似,都是直接模拟HTTP请求,而Scrapy也不能抓取JavaScript动态谊染的页面.在前面的博客中抓取Ja ...

  4. python爬虫——用selenium爬取京东商品信息

    1.先附上效果图(我偷懒只爬了4页)  2.京东的网址https://www.jd.com/ 3.我这里是不加载图片,加快爬取速度,也可以用Headless无弹窗模式 options = webdri ...

  5. 爬虫之selenium爬取京东商品信息

    import json import time from selenium import webdriver """ 发送请求 1.1生成driver对象 2.1窗口最大 ...

  6. 一起学爬虫——使用selenium和pyquery爬取京东商品列表

    layout: article title: 一起学爬虫--使用selenium和pyquery爬取京东商品列表 mathjax: true --- 今天一起学起使用selenium和pyquery爬 ...

  7. python制作爬虫爬取京东商品评论教程

    作者:蓝鲸 类型:转载 本文是继前2篇Python爬虫系列文章的后续篇,给大家介绍的是如何使用Python爬取京东商品评论信息的方法,并根据数据绘制成各种统计图表,非常的细致,有需要的小伙伴可以参考下 ...

  8. Scrapy实战篇(八)之Scrapy对接selenium爬取京东商城商品数据

    本篇目标:我们以爬取京东商城商品数据为例,展示Scrapy框架对接selenium爬取京东商城商品数据. 背景: 京东商城页面为js动态加载页面,直接使用request请求,无法得到我们想要的商品数据 ...

  9. selenium+phantomjs爬取京东商品信息

    selenium+phantomjs爬取京东商品信息 今天自己实战写了个爬取京东商品信息,和上一篇的思路一样,附上链接:https://www.cnblogs.com/cany/p/10897618. ...

随机推荐

  1. log_archive_dest_1设置报错

    DG搭建完之后,又报错: Tue Dec 22 16:24:33 2015 Errors in file /u01/app/oracle/admin/orcl/bdump/orcl_arc1_2994 ...

  2. android之GMS认证

    来到了新的公司,才知道做手机是须要做GMS认证的.于是从一个从没有做过GMS认证的小白到一个月做了8个项目的GMS认证.最后.自己都是吐了.每天晚上都是一个人傻傻在加班.更是知道了高通的支持力度让人发 ...

  3. IE6、IE7的兼容问题

    通常,网页的兼容问题,就是IE6\IE7的问题.表现为错位.换行,不支持CSS3等. 而其中,错位.换行,原因往往在于没有指明元素的width.height. 一般银瓦不告诉他.

  4. wox 快速搜索程序

    windows启动栏的搜索,会经常找不到exe. 使用wox可以非常快速的找到启动程序 https://github.com/Wox-launcher/Wox/ 安装完成后,默认alt+space出现 ...

  5. [Codeforces 1013B] And

    [题目链接] http://codeforces.com/problemset/problem/1013/B [算法] 不难发现,答案只有0,1,2,-1,共4种取值 分类讨论即可,计算时可以使用ST ...

  6. 在linux查看内存的大小

    用free -m查看的结果: # free -m          total    used    free     shared buffers     cached Mem:           ...

  7. PCB MS CLR 聚合函数 joinString加排序实现

    准备着手,动态列SQL查询,要实现动态列SQL,会运用到聚合函数,而SQL本身聚合函数有限, 无满足此用户任意字段组合变化,再加上工艺流程重复相同工序,如;沉铜1,沉铜2对应工序代码都是相同的 而通常 ...

  8. 有关于dict(字典)的特性与操作方法

    有关于dict(字典)的特性与操作方法 1.字典的特性 语法: dic = {key1 : value1,key2 : value2,key3 : value3............} 注:字典中k ...

  9. 「LOJ10150」括号配对

    [题目] Hecy 又接了个新任务:BE 处理.BE 中有一类被称为 GBE. 以下是 GBE 的定义: 空表达式是 GBE 如果表达式 A 是 GBE,则 [A] 与 (A) 都是 GBE 如果 A ...

  10. BZOJ 4563 错排+高精度

    思路: 把障碍移到对角线 就发现 这是个错位排列问题 用错排公式即可解 s[i]=(s[i-1]+s[i-2])*i //By SiriusRen #include <cstdio> #i ...