Python使用Selenium模块实现模拟浏览器抓取淘宝商品美食信息功能示例


Posted in Python onJuly 18, 2018

本文实例讲述了Python使用Selenium模块实现模拟浏览器抓取淘宝商品美食信息功能。分享给大家供大家参考,具体如下:

import re
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.common.exceptions import TimeoutException
from pyquery import PyQuery as pq
from bs4 import BeautifulSoup
from pymongo import MongoClient
from pymongo.errors import PyMongoError
url = 'http://www.taobao.com'
KEYWORD = '美食'
# monogdb配置信息
MONGO_HOST = "localhost"
MONGO_DATABASE = "taobao"
MONGO_TABLE = "meishi"
client = MongoClient(host=MONGO_HOST)
db = client[MONGO_DATABASE]
# PhantomJS 命令行相关配置
# 参见 http://phantomjs.org/api/command-line.html
SERVICE_ARGS = ['--disk-cache=true', '--load-images=false']
# driver = webdriver.Chrome() # 有界面
driver = webdriver.PhantomJS(service_args=SERVICE_ARGS) # 无界面
delay = 10
wait = WebDriverWait(driver, delay)
# print('windows size', driver.get_window_size())
# PhantomJs()的浏览器窗口很小,宽高只有400 * 300
driver.maximize_window() # 窗口最大化 # 对于PhantomJS来说设置窗口大小很关键,如果不设置,经常会出现问题
# driver.set_window_size(1920, 1080) # 设置浏览器窗口大小
# 模拟在淘宝网页中输入关键字搜索
def search():
  print("准备搜索 %s" % KEYWORD)
  try:
    driver.get(url)
    input_box = wait.until(
      EC.presence_of_element_located((By.CSS_SELECTOR, "input#q"))
    )
    search_btn = wait.until(EC.element_to_be_clickable(
      (By.CSS_SELECTOR, '#J_TSearchForm > div.search-button > button')))
    input_box.send_keys(KEYWORD)
    search_btn.click()
    total_page_str = wait.until(
      EC.presence_of_element_located(
        (By.CSS_SELECTOR, 'div.total'))).text
    total_page_num = int(re.search("(\d+)", total_page_str).group(1))
    item_list = get_goods_by_beautifulsoup()
    save_to_mongodb(item_list)
    return total_page_num
  except TimeoutError:
    print("搜索%s超时", KEYWORD)
    print("重新尝试搜索: %s", KEYWORD)
    search()
# 根据页码获取指定页数据,并将其保存到数据库中
def get_page(page_num):
  print("正在获取第%d页数据" % page_num)
  try:
    page_num_box = wait.until(
      EC.presence_of_element_located(
        (By.CSS_SELECTOR, "div.form > input")))
    ok_btn = wait.until(EC.element_to_be_clickable(
      (By.CSS_SELECTOR, 'div.form > span.btn.J_Submit')))
    page_num_box.clear()
    page_num_box.send_keys(page_num)
    ok_btn.click()
    wait.until(
      EC.text_to_be_present_in_element(
        (By.CSS_SELECTOR,
         'li.item.active > span.num'),
        str(page_num)))
    item_list = get_goods_by_beautifulsoup()
    save_to_mongodb(item_list)
  except TimeoutException:
    print("请求第%d页失败" % page_num)
    print("尝试重新获取第%d页" % page_num)
    return get_page(page_num)
def get_goods_by_pyquery():
  '''
  通过pyquery库解析数据
  获取商品的图片url、价格、标题、成交量、店铺名称、店铺位置
  '''
  wait.until(EC.presence_of_element_located(
    (By.CSS_SELECTOR, "#mainsrp-itemlist .items .item")))
  html = driver.page_source
  doc = pq(html)
  items = list(doc('#mainsrp-itemlist .items .item').items())
  for item in items:
    yield {
      # 不要用src属性,获取的图片地址很多是.gif图片,而非真实商品图片,
      'image': 'http://' + item.find('.J_ItemPic.img').attr('data-src'),
      'price': item.find('.price').text(),
      'title': item.find('.row > .J_ClickStat').text().strip(),
      'deal_cnt': item.find('.deal-cnt').text()[:-3],
      'shop': item.find('.shop').text(),
      'location': item.find('.location').text(),
    }
# 通过bs4解析数据
def get_goods_by_beautifulsoup():
  '''
  通过bs4库解析数据
  获取商品的图片url、价格、标题、成交量、店铺名称、店铺位置
  '''
  wait.until(EC.presence_of_element_located(
    (By.CSS_SELECTOR, "#mainsrp-itemlist .items .item")))
  html = driver.page_source
  soup = BeautifulSoup(html, 'lxml')
  items = soup.select('#mainsrp-itemlist .items .item')
  for item in items:
    yield {
      'image': 'http:' + item.select('img.J_ItemPic.img')[0]['data-src'],
      'price': item.select('div.price.g_price.g_price-highlight')[0].get_text(strip=True),
      'title': item.select('div.row.row-2.title > a.J_ClickStat')[0].get_text(strip=True),
      'deal_cnt': item.select('div.deal-cnt')[0].text[:-3],
      'shop': item.select('div.shop > a')[0].get_text(strip=True),
      'location': item.select('div.location')[0].text,
    }
def save_to_mongodb(item_list):
  for item in item_list:
    try:
      db[MONGO_TABLE].insert(item)  # insert支持插入多条数据
      print("mongodb插入数据成功:", item)
    except PyMongoError as e:
      print("mongodb插入数据失败:", item, e)
# 获取淘宝美食的图片url、价格、标题、成交量、店铺名称、店铺位置并将结果保存在mongodb数据库中
if __name__ == '__main__':
  try:
    total_pages = search()
    for page_num in range(2, total_pages + 1):
      get_page(page_num)
  except Exception as e:
    print("出错了", e)
  finally: # 确保 浏览器能正常关闭
    driver.close()

备注:

PhantomJS无界面浏览器打开的窗口默认大小400*300, 往往不能将网页加载完全,会给提取数据造成很大的困难,因此需要指定窗口大小。

可以使用 maximize_window() 最大化窗口或者set_window_size()设置指定大小

可能会出现的异常:

raise TimeoutException(message, screen, stacktrace)
selenium.common.exceptions.TimeoutException: Message:
Screenshot: available via screen

更多关于Python相关内容可查看本站专题:《Python Socket编程技巧总结》、《Python正则表达式用法总结》、《Python数据结构与算法教程》、《Python函数使用技巧总结》、《Python字符串操作技巧汇总》、《Python入门与进阶经典教程》及《Python文件与目录操作技巧汇总》

希望本文所述对大家Python程序设计有所帮助。

Python 相关文章推荐
python使用paramiko模块实现ssh远程登陆上传文件并执行
Jan 27 Python
Python3.x中自定义比较函数
Apr 24 Python
NumPy.npy与pandas DataFrame的实例讲解
Jul 09 Python
python遍历文件夹找出文件夹后缀为py的文件方法
Oct 21 Python
Python3爬虫爬取英雄联盟高清桌面壁纸功能示例【基于Scrapy框架】
Dec 05 Python
对python字典过滤条件的实例详解
Jan 22 Python
Python检查ping终端的方法
Jan 26 Python
用python3 urllib破解有道翻译反爬虫机制详解
Aug 14 Python
Python线程协作threading.Condition实现过程解析
Mar 12 Python
如何基于Python Matplotlib实现网格动画
Jul 20 Python
15个Pythonic的代码示例(值得收藏)
Oct 29 Python
PyQT5速成教程之Qt Designer介绍与入门
Nov 02 Python
python 将print输出的内容保存到txt文件中
Jul 17 #Python
python 实现对数据集的归一化的方法(0-1之间)
Jul 17 #Python
Python计算开方、立方、圆周率,精确到小数点后任意位的方法
Jul 17 #Python
python把数组中的数字每行打印3个并保存在文档中的方法
Jul 17 #Python
python3.x 将byte转成字符串的方法
Jul 17 #Python
Python 字符串转换为整形和浮点类型的方法
Jul 17 #Python
Python操作word常见方法示例【win32com与docx模块】
Jul 17 #Python
You might like
php zip文件解压类代码
2009/12/02 PHP
PHP5.3.1 不再支持ISAPI
2010/01/08 PHP
几个实用的PHP内置函数使用指南
2014/11/27 PHP
PHP内置的Math函数效率测试
2014/12/01 PHP
PHP比较运算符的详细介绍
2015/09/29 PHP
golang与php实现计算两个经纬度之间距离的方法
2016/07/22 PHP
php 利用socket发送GET,POST请求的实例代码
2020/07/04 PHP
namespace.js Javascript的命名空间库
2011/10/11 Javascript
js 实现css风格选择器(压缩后2KB)
2012/01/12 Javascript
jquery 事件冒泡的介绍以及如何阻止事件冒泡
2012/12/25 Javascript
JavaScript中的noscript元素属性位置及作用介绍
2013/04/11 Javascript
json字符串之间的相互转换示例代码
2014/08/21 Javascript
js图片轮播手动切换效果
2015/11/10 Javascript
jquery实现表格中点击相应行变色功能效果【实例代码】
2016/05/09 Javascript
JS添加删除DIV的简单实例
2016/07/08 Javascript
详谈Ajax请求中的async:false/true的作用(ajax 在外部调用问题)
2017/02/10 Javascript
关于Vue Webpack2单元测试示例详解
2017/08/14 Javascript
jQuery实现左右滑动的toggle方法
2018/03/03 jQuery
基于Vue组件化的日期联动选择器功能的实现代码
2018/11/30 Javascript
JavaScript创建、读取和删除cookie
2019/09/03 Javascript
vue项目中使用bpmn为节点添加颜色的方法
2020/04/30 Javascript
vue编写简单的购物车功能
2021/01/08 Vue.js
Python干货:分享Python绘制六种可视化图表
2018/08/27 Python
Python 实现两个列表里元素对应相乘的方法
2018/11/14 Python
解决python中0x80072ee2错误的方法
2020/07/19 Python
python openssl模块安装及用法
2020/12/06 Python
英国高档时尚男装购物网站:MR PORTER
2016/08/09 全球购物
Burberry英国官网:英国标志性奢侈品牌
2017/03/29 全球购物
美国本地交易和折扣网站:LocalFlavor.com
2017/10/26 全球购物
BIBLOO波兰:捷克的一家在线服装店
2018/03/09 全球购物
期末自我鉴定
2014/01/23 职场文书
献爱心大型公益活动策划方案
2014/09/15 职场文书
教师四风自我剖析材料
2014/09/30 职场文书
成品仓管员岗位职责
2015/04/01 职场文书
太行山上观后感
2015/06/05 职场文书
python_tkinter弹出对话框创建
2022/03/20 Python