使用selenium和pyquery爬取京东商品列表过程解析

今天一起学起使用selenium和pyquery爬取京东的商品列表。本文的所有代码是在pycharm IDE中完成的,操作系统window 10。

1、准备工作

安装pyquery和selenium类库。依次点击file->settings,会弹出如下的界面:

然后依次点击:project->project Interpreter->"+",,如上图的红色框所示。然后会弹出下面的界面:

输入selenium,在结果列表中选中“selenium”,点击“install package”按钮安装selenium类库。pyquery也是一样的安装方法。

安装chrome和chrome driver插件。chrome dirver插件下载地址:http://npm.taobao.org/mirrors/chromedriver/。 切记chrome和chrome dirver的版本要一致。我的chrome版本是70,对应chrome driver是2.44,2.43,2.42。

下载chrome driver解压后,将exe文件拷贝到pycharm开发空间的Scripts文件夹中:

2、分析要爬取的页面

这次是爬取京东图书中计算机书籍类书籍的信息。

打开chrome,打开开发者工具,输入www.jd.com,分析查询输入框和查询按钮的css代码:

通过分析发现,搜索框的css代码是id=“key”,查询按钮的css代码是class=“button”。下面是使用selenium调用chrome浏览器在搜索框输入关键词“计算机书籍”并点击查询按钮出发查询请求的代码:

from selenium import webdriver
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from pyquery import PyQuery as pq

#通过Chrome()方法打开chrome浏览器
browser = webdriver.Chrome()
#访问京东网站
browser.get("https://www.jd.com")
#等待50秒
wait = WebDriverWait(browser, 50)
#通过css选择器的id属性获得输入框
input = browser.find_element_by_id('key')
#在输入框中写入要查询的信息
input.send_keys('计算机书籍')
#获取查询按钮
submit_button = browser.find_element_by_class_name('button')
#点击查询按钮
submit_button.click()

上面代码成功启动chrome浏览器,自动完成在搜索框中输入关键词并点击查询按钮的操作。

点击完查询按钮之后,会加载出符合条件的书籍,如下图所示:

鼠标往下滚动到达网页底部时,会看到分页的界面:

下一步要做的工作就是分析商品列表页和分页的css代码。

我们要爬去图书的书名、图片、价格、出版社、评价数量信息。下图是商品列表也的界面,

通过开发者工具可知class="gl-item"的li节点是一条商品的信息,上图这个的红色框。

  • 绿色框是商品的图片信息。对应的是class=“p-img”的div节点。
  • 蓝色框是商品的价格信息,对应的是class="p-price"的div节点。
  • 黑色框是商品的名称信息,对应的是class="p-name"的div节点。
  • 紫色狂是商品的评价信息,对应的是class="p-commit"的div节点。
  • 褐色框是商品的出版社信息,对应的是class=“p-shopnum”的div节点。

我们使用pyquery解析商品的信息,使用selenium打开一个页面时,通过page_source属性就可以得到页面的源码。

这里有个坑需要注意:京东的商品列表页是显示固定数量的商品,当加载新的商品页的时候,并不是一下子把该页的商品都加载出来,而是鼠标向下滚动时才会动态加载新的商品。因此我们在使用selenium时,要将鼠标设置自动滚动到商品列表页的底部,这样就会把该页的所有商品都显示出现,爬取的数据才能完整,否则会出现丢失。

下面给出解析一个商品的代码:

from selenium import webdriver
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from pyquery import PyQuery as pq
import time
#通过Chrome()方法打开chrome浏览器
browser = webdriver.Chrome()
#访问京东网站
browser.get("https://www.jd.com")
#等待50秒
wait = WebDriverWait(browser, 50)
#通过css选择器的id属性获得输入框
input = browser.find_element_by_id('key')
#在输入框中写入要查询的信息
input.send_keys('计算机书籍')
#获取查询按钮
submit_button = browser.find_element_by_class_name('button')
#点击查询按钮
submit_button.click()

# 模拟下滑到底部操作
for i in range(1, 5):
  browser.execute_script("window.scrollTo(0, document.body.scrollHeight);")
  time.sleep(1)

#商品列表的总页数
total = wait.until(
  EC.presence_of_all_elements_located(
    (By.CSS_SELECTOR, '#J_bottomPage > span.p-skip > em:nth-child(1) > b')
  )
)

html = browser.page_source.replace('xmlns', 'another_attr')

doc = pq(html)
#一个商品信息是存放在class=“gl-item”的li节点内,items()方法是获取所有的商品列表。
li_list = doc('.gl-item').items()
#循环解析每个商品的信息
for item in li_list:
  image_html = item('.gl-i-wrap .p-img')
  book_img_url = item.find('img').attr('data-lazy-img')
  if book_img_url == "done":
    book_img_url = item.find('img').attr('src')
  print('图片地址:' + book_img_url)
  item('.p-name').find('font').remove()
  book_name = item('.p-name').find('em').text()
  print('书名:' + book_name)
  price = item('.p-price').find('em').text() + str(item('.p-price').find('i').text())
  print('价格:' + price)
  commit = item('.p-commit').find('strong').text()
  print('评价数量:' + commit)
  shopnum = item('.p-shopnum').find('a').text()
  print('出版社:' + shopnum)
  print('++++++++++++++++++++++++++++++++++++++++++++')

对于有分页的情况,需要一页一页的解析商品,我们可以通过selenium调用“下一页”按钮来获取下一页的源代码。我们来分析下一页的css代码,滚动鼠标到网页的底部,会看到分页的情况:

通过上图可知,需要获取到“下一页”按钮,然后调用click方法。相应的代码为:

  next_page_button = wait.until(
    EC.element_to_be_clickable((By.CSS_SELECTOR, '#J_bottomPage > span.p-num > a.pn-next > em'))
  )
  next_page_button.click()

  #滑动到页面底部,用于加载数据
  for i in range(0,3):
    browser.execute_script("window.scrollTo(0, document.body.scrollHeight);")
    time.sleep(10)

  #一页显示60个商品,"#J_goodsList > ul > li:nth-child(60)确保60个商品都正常加载出来。
  wait.until(
    EC.presence_of_all_elements_located((By.CSS_SELECTOR, "#J_goodsList > ul > li:nth-child(60)"))
  )
  # 判断翻页成功,当底部的分页界面上显示第几页时,就显示翻页成功。
  wait.until(
    EC.text_to_be_present_in_element((By.CSS_SELECTOR, "#J_bottomPage > span.p-num > a.curr"), str(page_num))
  )

下面给出完整代码:

from selenium import webdriver
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from pyquery import PyQuery as pq
import time
#打开不同的浏览器实例
def openBrower(brower_type):
  if brower_type == 'chrome':
    return webdriver.Chrome()
  elif brower_type == 'firefox':
    return webdriver.Firefox()
  elif brower_type == 'safari':
    return webdriver.Safari()
  elif brower_type == 'PhantomJS':
    return webdriver.PhantomJS()
  else :
    return webdriver.Ie()
def parse_website():
  # 通过Chrome()方法打开chrome浏览器
  browser = openBrower('chrome')
  # 访问京东网站
  browser.get("https://www.jd.com")
  # 等待50秒
  wait = WebDriverWait(browser, 50)
  # 通过css选择器的id属性获得输入框。until方法表示浏览器完全加载到对应的节点,才返回相应的对象。presence_of_all_elements_located是通过css选择器加载节点
  input = wait.until(
    EC.presence_of_all_elements_located((By.CSS_SELECTOR, '#key'))
  )

  # input = browser.find_element_by_id('key')
  # 在输入框中写入要查询的信息
  input[0].send_keys('计算机书籍')
  # 查询按钮完全加载完毕,返回查询按钮对象
  submit_button = wait.until(
    EC.element_to_be_clickable((By.CSS_SELECTOR, '.button'))
  )
  # 点击查询按钮
  submit_button.click()

  # 模拟下滑到底部操作
  for i in range(0,3):
    browser.execute_script("window.scrollTo(0, document.body.scrollHeight);")
    time.sleep(3)

  # 商品列表的总页数
  total = wait.until(
    EC.presence_of_all_elements_located(
      (By.CSS_SELECTOR, '#J_bottomPage > span.p-skip > em:nth-child(1) > b')
    )
  )
  html = browser.page_source.replace('xmlns', 'another_attr')
  parse_book(1,html)

  for page_num in range(2,int(total[0].text) + 1):
    parse_next_page(page_num,browser,wait)

##解析下一页
def parse_next_page(page_num,browser,wait):

  next_page_button = wait.until(
    EC.element_to_be_clickable((By.CSS_SELECTOR, '#J_bottomPage > span.p-num > a.pn-next > em'))
  )
  next_page_button.click()

  #滑动到页面底部,用于加载数据
  for i in range(0,3):
    browser.execute_script("window.scrollTo(0, document.body.scrollHeight);")
    time.sleep(10)

  #一页显示60个商品,"#J_goodsList > ul > li:nth-child(60)确保60个商品都正常加载出来。
  wait.until(
    EC.presence_of_all_elements_located((By.CSS_SELECTOR, "#J_goodsList > ul > li:nth-child(60)"))
  )
  # 判断翻页成功,当底部的分页界面上显示第几页时,就显示翻页成功。
  wait.until(
    EC.text_to_be_present_in_element((By.CSS_SELECTOR, "#J_bottomPage > span.p-num > a.curr"), str(page_num))
  )

  html = browser.page_source.replace('xmlns', 'another_attr')
  parse_book(page_num, html)

def parse_book(page,html):
  doc = pq(html)
  li_list = doc('.gl-item').items()
  print('-------------------第' + str(page) + '页的图书信息---------------------')
  for item in li_list:
    image_html = item('.gl-i-wrap .p-img')
    book_img_url = item.find('img').attr('data-lazy-img')
    if book_img_url == "done":
      book_img_url = item.find('img').attr('src')
    print('图片地址:' + book_img_url)
    item('.p-name').find('font').remove()
    book_name = item('.p-name').find('em').text()
    print('书名:' + book_name)
    price = item('.p-price').find('em').text() + str(item('.p-price').find('i').text())
    print('价格:' + price)
    commit = item('.p-commit').find('strong').text()
    print('评价数量:' + commit)
    shopnum = item('.p-shopnum').find('a').text()
    print('出版社:' + shopnum)
    print('++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++')

def main():
  parse_website()
if __name__ == "__main__":
  main()

3、总结

(1)要记得调用 browser.execute_script("window.scrollTo(0, document.body.scrollHeight);")方法模拟鼠标向下滚动的操作加载数据,否则数据会不完整。

(2)在通过page_source获取网页源码时,如果有xmlns命名空间,则要将该命名空间空其他的字段代替,否则使用pyquery解析网页时,会解析不出数据。pyquery解析xmlns命名空间时,会自动隐藏掉某些属性。导致无法征程解析网页,原因不详,如果有人知道原因请告知。

(3)尽量用wait.until(EC.presence_of_all_elements_located())方法,这样可以避免网页无法正常加载而提前返回网页信息的情况。保证数据的准确。

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持我们。

时间: 2019-08-14

python selenium爬取斗鱼所有直播房间信息过程详解

还是分析一下大体的流程: 首先还是Chrome浏览器抓包分析元素,这是网址:https://www.douyu.com/directory/all 发现所有房间的信息都是保存在一个无序列表中的li中,所以我们可以先获取一个装有li的element对象的列表,然后在对每个element逐一操作 分析斗鱼的翻页,有一个下一页按钮,是个li,class="dy-Pagination-item-custom" ,但是当烦到最后一页的时候,class="dy-Pagination-di

python爬虫selenium和phantomJs使用方法解析

1.selenum:三方库.可以实现让浏览器完成自动化的操作. 2.环境搭建 2.1 安装: pip install selenium 2.2 获取浏览器的驱动程序 下载地址: http://chromedriver.storage.googleapis.com/index.html http://npm.taobao.org/mirrors/chromedriver/ 浏览器版本和驱动版本的对应关系表: chromedriver版本 支持的Chrome版本 v2.46 v71-73 v2.45

Python爬虫辅助利器PyQuery模块的安装使用攻略

Windows下的安装: 下载地址:https://pypi.python.org/pypi/pyquery/#downloads 下载后安装: C:\Python27>easy_install E:\python\pyquery-1.2.4.zip 也可以直接在线安装: C:\Python27>easy_install pyquery pyquery是一个类似jquery的python库,可以使用像jquery那样的语法来提取网页中的任何数据,这个用于html网页的数据提取和挖掘还是一个很不

Python中的jquery PyQuery库使用小结

pyquery库是jQuery的Python实现,可以用于解析HTML网页内容,使用方法: 复制代码 代码如下: from pyquery import PyQuery as pq 1.可加载一段HTML字符串,或一个HTML文件,或是一个url地址,例: 复制代码 代码如下: d = pq("<html><title>hello</title></html>")d = pq(filename=path_to_html_file)d =

python中selenium操作下拉滚动条的几种方法汇总

UI自动化中经常会遇到元素识别不到,找不到的问题,原因有很多,比如不在iframe里,xpath或id写错了等等:但有一种是在当前显示的页面元素不可见,拖动下拉条后元素就出来了. 比如下面这样一个网页,需要进行拖动下拉条后才能通过selenium找到密码输入框的元素, 在python中有几种方法解决这种问题,简单介绍下,给需要的人: 方法一)使用js脚本直接操作,方法如下: js="var q=document.getElementById('id').scrollTop=10000"

Python + selenium自动化环境搭建的完整步骤

前言 本文主要介绍了关于Python+selenium自动化环境搭建的相关内容,分享出来供大家参考学习,下面话不多说了,来一起看看详细的介绍吧 Python +selenium+googledriver 小白的血泪安装使,不停的总结写心得是理解透彻的毕竟之路 一,python的安装: 首先去Python的官网下载安装包:https://www.python.org/  ,大家也可以通过我们进行下载://www.jb51.net/softs/415916.html 2.下载完成后如下图所示 3.双

python+selenium自动化框架搭建的方法步骤

环境及使用软件信息 python 3 selenium 3.13.0 xlrd 1.1.0 chromedriver HTMLTestRunner 说明: selenium/xlrd只需要再python环境下使用pip install 名称即可进行对应的安装. 安装完成后可使用pip list查看自己的安装列表信息. chromedriver:版本需和自己的chrome浏览器对应,百度下载. 作用:对chrome浏览器进行驱动. HTMLTestRunner:HTMLTestRunner是Pyt

python selenium自动化测试框架搭建的方法步骤

设计思路 本文整理归纳以往的工作中用到的东西,现汇总成基础测试框架提供分享. 框架采用python3 + selenium3 + PO + yaml + ddt + unittest等技术编写成基础测试框架,能适应日常测试工作需要. 1.使用Page Object模式将页面定位和业务操作分开,分离测试对象(元素对象)和测试脚本(用例脚本),一个页面建一个对象类,提高用例的可维护性: 2.使用yaml管理页面控件元素数据和测试用例数据.例如元素ID等发生变化时,不需要去修改测试代码,只需要在对应的

python+webdriver自动化环境搭建步骤详解

python是一个很好脚本语言工具,现在也比较流行的一个脚本语言工具,对目前web自动化可以用的比较是webdriver框架进行自动化测试,脚本写起来较简单,运行的占用的内容较小.那么对windown下python+webdriver自动化环境如何进行搭建. 下载一个python.exe文件,直接默认安装即可 配置python的环境,指定到python的路径 安装pip环境,从网上下载一个pip,解压完成后,进入解压目录下执行python setup install 安装selenium文件,在

python+selenium开发环境搭建图文教程

web 调试工具介绍和开发环境搭建 python与selenium开发环境搭建: 一.下载python软件:https://www.python.org/ 下载完后,进行安装,安装成功后,打开IDLE(Python 3.6.2),如下图: 如上图在里面输入print("Hello Wrod!")按回车,出现Hello Wrod!,说明已经把IDLE装好了,下面打开dos命令窗口输入Python按回车.如下图: 出现python版本号等信息说明python已经安装成功.如果出现错误信息,

本地HTTPS环境搭建的完整步骤记录

前言 之前在为公司的应用添加 https 时,是在 nginx 上配置的,这样不需要 node 做额外的开发,但是组内的开发同学本地一直没有配置,一直是采用 http 的方式开发和测试.最近发现有些 case 需要 https 来复现,比如 Android 5.0 以上的 app 内,使用 https 的网站访问 http 的内容会阻止访问,这种问题测试的时候本地就需要一个 https 的环境.于是花了点时间学习了下本地 https 的搭建,在这里记录一下.下面话不多说了,来一起看看详细的介绍吧

Python 离线工作环境搭建的方法步骤

准备 在断网的和联网的机器安装pip,下载地址https://pypi.python.org/pypi/pip 在联网的开发机器上安装好需要的包 例如: pip3 install paramiko pip3 install fabric 打包已安装的包 新建pyenv文件夹用来存储下载下来的所需安装包 pip3 list #查看安装的包 #使用pip导出当前环境所有依赖包信息文件 pip3 freeze >requirements.txt # 下载所有依赖包到本地 pip3 install -r

Python selenium 自动化脚本打包成一个exe文件(推荐)

目标 打包Python selenium 自动化脚本(如下run.py文件)为exe执行文件,使之可以直接在未安装python环境的windows下运行 run.py文件源码: 文件路径:D:\gongcheng 注:chromedriver.exe 文件在D:\gongcheng目录下 #!/usr/bin/python3 # encoding:utf-8 from selenium import webdriver import time as t brw = webdriver.Chrom

学习Python selenium自动化网页抓取器

直接入正题---Python selenium自动控制浏览器对网页的数据进行抓取,其中包含按钮点击.跳转页面.搜索框的输入.页面的价值数据存储.mongodb自动id标识等等等. 1.首先介绍一下 Python selenium ---自动化测试工具,用来控制浏览器来对网页的操作,在爬虫中与BeautifulSoup结合那就是天衣无缝,除去国外的一些变态的验证网页,对于图片验证码我有自己写的破解图片验证码的源代码,成功率在85%. 详情请咨询QQ群--607021567(这不算广告,群里有好多P

selenium+java环境搭建过程推荐

这篇文章主要介绍了selenium+java环境搭建过程推荐,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下 先前自己搭过一次环境,以为自己已经记住了.今天换了一台电脑重新搭建的时候,才发现那是错觉-- 今天重新把环境搭了一遍,并记录下来,供以后温习. 整体步骤如下: 1.jdk安装: 安装完成之后主要是--jdk的环境变量配置:path.CALSSPATH.JAVA_HOME的配置: 验证方法:在cmd里面输一下Java.javac能够正常显示