详解基于python +Selenium的爬虫

一.背景

1. Selenium

Selenium 是一个用于web应用程序自动化测试的工具,直接运行在浏览器当中,支持chrome、firefox等主流浏览器。可以通过代码控制与页面上元素进行交互(点击、输入等),也可以获取指定元素的内容

2.优劣

劣势:

  • 相比于抓包→构造请求→解析返回值的爬虫,由于Selenium需要生成一个浏览器环境,所有操作(与元素交互、获取元素内容等)均需要等待页面加载完毕后才可以继续进行,所以速度相比构造请求的慢很多。
  • 对于为了反爬做了特殊处理的展示内容,如字体加密(参考猫眼)、图片替换数字(参考自如)等,可能取不到想要的数据。

使用图片替换数字的自如:

做了字体加密的猫眼:

优势:

  • 不需要做复杂的抓包、构造请求、解析数据等,开发难度相对要低一些。
  • 其访问参数跟使用浏览器的正常用户一模一样,访问行为也相对更像正常用户,不容易被反爬虫策略命中。
  • 生成的浏览器环境可以自动运行 JS 文件,所以不用担心如何逆向混淆过的JS文件生成用作人机校验的参数,如马蜂窝酒店评论的人机校验参数_sn,网易云音乐评论的人机校验参数paramsencSecKey。可以自行抓包查看。
  • 如果需要抓取同一个前端页面上面来自不同后端接口的信息,如OTA酒店详情页的酒店基础信息、价格、评论等,使用Selenium可以在一次请求中同时完成对三个接口的调用,相对方便。

二、实现

1.环境

python3.6 + Macos

2.依赖包

Selenium

安装的时候是大写的 S ,import的时候是 小写 s。

pip install Selenium

3.浏览器驱动(webdriver)

加载浏览器环境需要下载对应的浏览器驱动,此处选择 Chrome。

下载地址:http://npm.taobao.org/mirrors/chromedriver/ ,选择合适的版本下载解压后放在随便一个位置即可。

4.hello world

from selenium import webdriver'''这里填刚刚下载的驱动的路径'''
path = '/Applications/Google Chrome.app/Contents/chromedriver'driver = webdriver.Chrome(executable_path=path)url = 'http://hotel.qunar.com/city/beijing_city/'
driver.get(url)'''运行上述代码,会打开一个浏览器,并且加载去哪儿的酒店列表页'''

这时候可以通过webdriver自带的一些的一些方法获取元素内容或者与元素进行交互。

#返回ID = js_block_beijing_city_7810的元素信息
hotel_info = driver.find_element_by_id('js_block_beijing_city_7810')
print(hotel_info.text)
#返回 展示在列表页的酒店信息
#同理,可以find_element_by_[class_name|name] 等,均可完成查询。

也可以通过方法 find_elements查找符合某条件的一组元素,以列表的形式返回。

#当需要查询的唯一标识带有空格时,可以使用find_elements_by_css_selector,否则会报错。
hotel_list = driver.find_elements_by_css_selector("[class='b_result_box js_list_block  b_result_commentbox']")
print(hotel_list)
#返回酒店列表的全部信息。

5.关闭图片加载

在不需要抓取图片的情况下,可以设置不加载图片,节约时间,这样属于调整本地设置,在传参上并不会有异常。

from selenium import webdriverchrome_opt = webdriver.ChromeOptions()
prefs={"profile.managed_default_content_settings.images":2}
chrome_opt.add_experimental_option("prefs",prefs)path = '' #驱动路径
browser_noPic = webdriver.Chrome(executable_path=path,chrome_options=chrome_opt)

三、使用webdriver与元素进行交互

1.模拟鼠标点击

hotel_info = driver.find_element_by_id("js_plugin_tag_beijing_city_7810")
hotel.info.click()
#进入酒店详情页

2.模拟键盘输入

hotel_search = driver.find_element_by_id("jxQ")
hotel_search.send_keys("如")
hotel_search.send_keys("如家")
#由于搜索框输入的第一个字会被选中,所以需要第二次才能完整输入,当然也可以模拟按键盘的 →(右键)取消选中后再次输入。

3.模拟下拉

webdriver中对鼠标的操作的方法封装在ActionChains类中 ,使用前要先导入ActionChains类:

from selenium.webdriver.common.action_chains import  ActionChains"""在页面顶部、底部个找了一个元素,并模拟鼠标从顶到底的滑动"""
start = driver.find_element_by_class_name('e_above_header')
target = driver.find_element_by_class_name('qn_footer')
ActionChains(driver).drag_and_drop(start,target).perform()

此外,webdiver还提供丰富的交互功能,比如鼠标悬停、双击、按住左键等等,此处不展开介绍。

四、一个完整的模拟浏览器爬虫

from selenium import webdriver
from selenium.webdriver.common.action_chains import  ActionChains
import time'''这里填刚刚下载的驱动的路径'''
path = '/Users/./Desktop/chromedriver'
driver = webdriver.Chrome(executable_path=path)url = 'http://hotel.qunar.com/city/beijing_city/'
driver.get(url) time.sleep(6) #等待页面加载完再进行后续操作"""在页面顶部、底部个找了一个元素,并模拟鼠标从顶到底的滑动"""
start = driver.find_element_by_class_name('e_above_header')
target = driver.find_element_by_class_name('qn_footer')
ActionChains(driver).drag_and_drop(start,target).perform()time.sleep(5) #等待页面加载完再进行后续操作hotel_link_list = driver.find_elements_by_css_selector("[class='item_price js_hasprice']")
print("在此页面共有酒店",len(hotel_link_list),"家")
windows = driver.window_handles#此处可以爬整个页面任何想要想要的元素
list_hotel_info=[]
def hotel_info_clawer():list_hotel_info.append([driver.find_element_by_class_name("info").text,driver.find_element_by_class_name("js-room-table").text,driver.find_element_by_class_name("dt-module").text])for i in range(len(hotel_link_list)):hotel_link_list[i].click()driver.switch_to.window(windows[-1]) #切换到刚打开的酒店详情页hotel_info_clawer()driver.close() #关闭已经爬完的酒店详情页    print("已经抓取酒店",i,"家")#后面可以补充翻页继续抓取的部分

五、使用截图+OCR抓取关键数据

对于做了特殊处理的信息,如上述的猫眼电影的票房信息、自如的价格等,不适用于直接获取制定元素的信息进行抓取,可以使用截图+OCR的方式抓取此类数据。

以自如的房租为例:

from selenium import webdriver'''这里填刚刚下载的驱动的路径'''
path = '/Applications/Google Chrome.app/Contents/chromedriver'
driver = webdriver.Chrome(executable_path=path)url = 'http://www.ziroom.com/z/vr/61715463.html'
driver.get(url)price = diver.find_element_by_class_name('room_price')print(price.text)#由于自如的价格用图片做了替换,这样并不能获取到实际价格,需要获取图片再做ocr处理"对指定元素部分截图再保存"
price.screenshot('/Users/./Desktop/price.png')

安装ocr工具:

Tesseract是一个开源的OCR引擎,能识别100多种语言(中,英,韩,日,德,法...等等),但是Tesseract对手写的识别能力较差,仅适用于打印字体。

//仅安装tesseract,不安装训练工具和其他语音包,需要识别中文的话得额外下载
//下载地址:https://github.com/tesseract-ocr/tessdata
brew install tesseract

使用Tesseract:

tesseract ~/price.png result
//识别图片并将结果存在result里面

在python下使用Tesseract:

首先安装依赖包:pip install pytesseract

import pytesseract
from PIL import Image# open image
image = Image.open('price.png')
code = pytesseract.image_to_string(image)
print(code)

六、待填坑

  • 操作鼠标滑动滑块

python selenium爬虫_详解基于python +Selenium的爬虫相关推荐

  1. 利用python处理dna序列_详解基于python的全局与局部序列比对的实现(DNA)

    程序能实现什么 a.完成gap值的自定义输入以及两条需比对序列的输入 b.完成得分矩阵的计算及输出 c.输出序列比对结果 d.使用matplotlib对得分矩阵路径的绘制 一.实现步骤 1.用户输入步 ...

  2. python微博评论爬虫_详解用python写网络爬虫-爬取新浪微博评论 基于Python的新浪微博爬虫研究...

    怎样爬取新浪微博的评论信息 针对八爪鱼在微博的应用上,除了用户信息之外还包括话题内容方面的采集,目前绝大多数企业均在微博设有官方微博,八爪鱼可以协助企业快速及时的抓取与企业产品相关联的话题信息,规则市 ...

  3. python两张图片无缝合成一张_详解基于python的多张不同宽高图片拼接成大图

    #!/usr/bin/env python # -*- coding:utf-8 -*- import PIL.Image as Image import os IMAGES_PATH = 'D:Ma ...

  4. 使用python下载文件_详解使用Python下载文件的几种方法

    在使用Python进行数据抓取的时候,有时候需要保持文件或图片等,在Python中可以有多种方式实现.今天就一起来学习下. urllib.request 主要使用的是urlretrieve方法,该方法 ...

  5. 用python3做学生管理系统_详解用python实现基本的学生管理系统(文件存储版)(python3)...

    详解用python实现基本的学生管理系统(文件存储版)(python3) 来源:中文源码网    浏览: 次    日期:2019年11月5日 详解用python实现基本的学生管理系统(文件存储版)( ...

  6. python编写数据库连接工具_详解使用Python写一个向数据库填充数据的小工具(推荐)...

    一. 背景 公司又要做一个新项目,是一个合作型项目,我们公司出web展示服务,合作伙伴线下提供展示数据. 而且本次项目是数据统计展示为主要功能,并没有研发对应的数据接入接口,所有展示数据源均来自数据库 ...

  7. python zxing 识别条码_详解利用python识别图片中的条码(pyzbar)及条码图片矫正和增强...

    前言 这周和大家分享如何用python识别图像里的条码.用到的库可以是zbar.希望西瓜6辛苦码的代码不要被盗了.(zxing的话,我一直没有装好,等装好之后再写一篇) 具体步骤 前期准备 用open ...

  8. python解释器在哪里_详解查看Python解释器路径的两种方式

    进入python的安装目录, 查看python解释器 进入bin目录 # ls python(看一下是否有python解释器版本) # pwd (查看当前目录) 复制当前目录即可 1. 通过脚本查看 ...

  9. 用python写管理系统局域网_详解用python -m http.server搭一个简易的本地局域网

    工作时同事间几mb小文件的传输,一般使用QQ或者微信就足够了,但当传输文件几百MB或者几十G时,这种方法的效率就显得不足了.本篇就是简单说明一个python小功能,让大家能利用python方便的搭建一 ...

最新文章

  1. rust(10)-函数指针
  2. 街景图像分割_借助深度学习和街景图像进行城市的大规模树木死亡率研究
  3. 如何使用VisualVM监视服务器上的多个JVM
  4. 前端页面内含外显相关知识
  5. 初识Spring Security
  6. python3写文件_python3 写文件问题
  7. MySQL Query Cache 小结
  8. SVN 代码与文件管理小记
  9. 统计信号处理基础-估计与检测理论的学习过程
  10. ezcad旋转轴标刻参数_EzCad 2.0 扩展轴标刻插件使用说明书简体中文(.pdf
  11. HART协议详解:HART与MCU通信代码解析举例
  12. Arrays.sort()和lambda表达式
  13. win10系统如何telnet服务器,win10专业版官网系统如何开启telnet服务的办法
  14. RC522(RFID模块)实践总结
  15. python中chr65_Python语句 print(chr(65))的运行结果是
  16. 鏈接腳本、靜態庫、共享庫
  17. 傅里叶变换 ~ 离散傅里叶变换(DFT)
  18. 中英文职位对照之 会计与财务
  19. Mysql_use_result和Mysql_store_result
  20. “IND-”安全概念的简单解释(IND-CPA,IND-CCA等)

热门文章

  1. 如何使用SAP事务码SAT进行UI应用的性能分析
  2. 什么是ABAP的STATE_READ_ACCESS
  3. why we see different http status code like 404, 500. where are they handled
  4. 如何通过url访问的方式获取HANA report的元数据metadata
  5. one order callback frequency
  6. tcode SMQS
  7. SAP WebIDE里的JavaScript代码检查code check
  8. 为什么SAP UI5框架在应用整个生命周期只调用onBeforeRendering一次
  9. SAP Cloud for Customer Extensibility的设计与实现
  10. oracle时间类型转化成java对象_Oracle数据库date类型与Java中Date的联系与转化