文章目录

  • Introduction
  • Installation
    • libraries
    • drivers
  • WebDriver
    • Find Element
      • By
      • driver.find_element(s)
      • driver.switch_to.active_element
    • Keyboard
      • send_keys
      • key_down
      • key_up
      • clear
    • Mouse
      • Click
      • Drag-and-drop
    • Http proxies
    • Page loading strategy
  • Selenium 爬取谷歌图片
    • 自动搜索
    • 页面跳转
    • 得到所有图片元素
      • 下拉到底部
      • 获取所有图片元素
    • 下载图片
  • 完整代码
    • 结果

在之前的 Python爬虫爬取Google图片 ,给出了从谷歌图片搜索结果的动态网页上爬取图片的方法,这个方法需要我们手动通过检查元素进行页面元素相关代码的复制,但是显然,我们更希望让脚本也可以完成这个工作,而我们只需要告诉这个脚本哪部分元素是我们需要的,这就涉及到了两个问题:

  • 如何模拟用户和浏览器的交互操作
  • 如何检查元素

我们需要用到一个工具集——Selenium

Introduction


Selenium 是一个工具集,并不仅仅只是 python 的一个 package,对于 JavaRuby 等也有相关的实现,可以实现远程控制浏览器并模拟用户和模拟器的交互操作。

Installation


这里给出 python 的安装方法

libraries

pip install selenium

如果是使用源代码安装的话,则需要下载相关的压缩文件,然后执行:

python setup.py install

drivers

安装对应浏览器的驱动。对应大部分的浏览器的驱动,都需要指定一个可执行文件使得 Selenium 可以和浏览器进行对接,以 Windows 为例:

  • 创建一个文件夹例如 C:\WebDriver\bin
  • 新增相应的值到环境变量 Path

WebDriver


一个适用于不同语言的API以及协议(protocol),用于处理 selenium 和浏览器之间的交流,从而控制浏览器的行为。对于几乎所有的主流浏览器都有对应的接口。
截至 2020-07-19 对不同浏览器的支持情况:

Browser Maintainer Versions Supported
Chrome Chromium All versions
Firefox Mozilla 54 and newer
Internet Explorer Selenium 6 and newer
Opera Opera Chromium / Presto 10.5 and newer
Safari Apple 10 and newer

Find Element

By

顾名思义,即我们搜索元素的依据

from selenium import webdriver
from selenium.webdriver.common.by import By

driver.find_element(s)

元素搜索的函数:

from selenium import webdriver
from selenium.webdriver.common.by import Bydirver = webdriver.Chrome()
driver.get("https://www.example.com")# 获取第一个 div 标签元素
div = driver.find_element(By.TAG_NAME, "div")# 获取所有段落
ps = driver.find_elements(By.TAG_NAME, "p")
for p in ps:print(e.text)

driver.switch_to.active_element

切换到当前选中的元素(即 active),并获取相关标签信息:

# 通过模拟用户的输入得到一个活跃的元素
driver = webdriver.Chrome()
driver.get("https://www.google.com")
driver.find_element(By.CSS_SELECTOR, '[name="q"]').send_keys("webElement")# 切换到当前的活跃元素,获取相关标签的内容
attr = driver.switch_to.active_element.get_attribute("title")

Keyboard

模拟用户的键盘输入:

send_keys

输入文本,并且可以模拟键盘输入:

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys# 模拟页面跳转
driver.get("https://www.google.com")# 输入 “webdriver” 并且模拟 enter 键输入
driver.find_element(By.NAME, "q").send_keys("webdriver" + Keys.ENTER)

key_down

模拟 shiftctrlalt 的按键效果,例如 ctrl + A 进行页面全选:

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys# 模拟页面跳转
driver.get("https://www.google.com")# 全选页面
driver.ActionChains(driver).key_down(Keys.CONTROL).send_keys("a").perform()

key_up

结合 key_down 使用,即输入包含大小写交替出现时,通过 key_downkey_up 切换,同样通过 ActionChains 实现用户的串联输入操作。

clear

清除内容:

text = driver.find_element(By.TAG_NAME, "input")
text.send_keys("pokemon")
# 清除内容
text.clear()

Mouse

模拟用户的鼠标操作

Click

同样通过 ActionChains 来实现

# 获取隐藏目录,例如下拉目录
menu = driver.find_element_by_css_selector(".nav")
hidden_submenu = driver.find_element_by_css_selector(".nav #submenu1")actions = ActionChains(driver)
# 将鼠标定位到相应的元素
actions.move_to_element(menu)
# 点击操作
actions.click(hidden_submenu)
actions.perform()

Drag-and-drop

通过 ActionChains1drag_and_drop 来实现,将一个元素拖拽到另一个元素上:

source = driver.find_element(By.ID, "source")
target = driver.find_element(By.ID, "target")
ActionChains(driver).drag_and_drop(source, target).perform()

Http proxies

定义 Http 传输协议

from selenium import webdriverPROXY = "<HOST:PORT>"
webdriver.DesiredCapabilities.FIREFOX['proxy'] = {"httpProxy": PROXY,"ftpProxy": PROXY,"sslProxy": PROXY,"proxyType": "MANUAL",}with webdriver.Firefox() as driver:# Open URLdriver.get("https://selenium.dev")

Page loading strategy

设置浏览器的加载策略:

  • normal:等待网页完全加载完毕
  • eager:只加载初始文档,不包括初始文档加载的内容(即只能抓取静态网页的内容,不能抓取动态网页),即 DOMContentLoaded 事件结果返回时
  • none:只加载初始文档
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
options = Options()
options.page_load_strategy = 'strategy' # normal, eager, none
driver = webdriver.Chrome(options=options)
# Navigate to url
driver.get("http://www.google.com")
driver.quit()

Selenium 爬取谷歌图片


正题,现在我们尝试完全依靠 python 脚本实现自动爬取谷歌图片。我们需要实现:

  • 自动搜索并跳转
  • 从网页元素中找到包含所有图片的页面元素,得到所有图片标签中的 url
  • 下载图片

自动搜索

我们需要模拟鼠标点击通过 ActionChains 来实现:

# search on google
# navigate to url
self.driver.get(self.url)
# locate input field
search_input = self.driver.find_element(By.NAME, 'q')
# emulate user input and enter to search
webdriver.ActionChains(self.driver).move_to_element(search_input).send_keys("pokemon" + Keys.ENTER).perform()

页面跳转

点击跳转到图片搜索结果:

# navigate to google image
# find navigation buttons
self.driver.find_element(By.LINK_TEXT, '图片').click()

得到所有图片元素

这里可以结合我们之前使用的 BeautifulSoup 来实现,此时需要读取检查元素页面中对应部分的 html 代码,并且大部分情况下,使用 BeautifulSoup 是更加高效的,因为 WebDriver 需要对所有的 DOM 元素进行遍历。但是 WebDriver 的优势在于可以自动实现网页的下拉,从而可以爬取到所有的搜索结果,这里我们介绍使用 Selenium 的相关实现:

下拉到底部

# load more images as many as possible
# 通过让驱动执行js脚本实现下拉
self.driver.execute_script("window.scrollTo(0, document.body.scrollHeight)")
# 找到加载按钮
show_more_button = self.driver.find_element(By.CSS_SELECTOR, "input[value='显示更多搜索结果']")
try:while True:# 根据浏览器信息message = self.driver.find_element(By.CSS_SELECTOR, 'div.OuJzKb.Bqq24e').get_attribute('textContent')# print(message)if message == '正在加载更多内容,请稍候':self.driver.execute_script("window.scrollTo(0, document.body.scrollHeight)")elif message == '新内容已成功加载。向下滚动即可查看更多内容。':# scrolling to bottomself.driver.execute_script("window.scrollTo(0, document.body.scrollHeight)")# 当出现加载更多的按钮时,点击加载更多if show_more_button.is_displayed():show_more_button.click()# 没有更多图片可以加载时退出elif message == '看来您已经看完了所有内容':break# 点击重试,这个地方没有测试elif message == '无法加载更多内容,点击即可重试。':show_more_button.click()else:self.driver.execute_script("window.scrollTo(0, document.body.scrollHeight)")
except Exception as err:print(err)

获取所有图片元素

# find all image elements in google image result page
imgs = self.driver.find_elements(By.CSS_SELECTOR, "img.rg_i.Q4LuWd")

下载图片

这里和 BeautifulSoup 部分实现相同,:

img_count = 0
for img in imgs:try:# image per secondtime.sleep(1)print('\ndownloading image ' + str(img_count) + ': ')img_url = img.get_attribute("src")path = os.path.join(imgs_dir, str(img_count) + "_img.jpg")request.urlretrieve(url = img_url, filename = path, reporthook = progress_callback, data = None)img_count = img_count + 1except error.HTTPError as http_err:print(http_err)except Exception as err:print(err)

完整代码

最终,完整部分的代码如下:

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.chrome.options import Optionsfrom urllib import error
from urllib import request
import os
import time
import sys# default url
# replace for yours
url = "https://www.google.com"
explorer = "Chrome"
# directory
imgs_dir = "./images"# report hook with three parameters passed
# count_of_blocks  The number of blocks transferred
# block_size The size of block
# total_size Total size of the file
def progress_callback(count_of_blocks, block_size, total_size):# determine current progressprogress = int(50 * (count_of_blocks * block_size) / total_size)if progress > 50:progress = 50# update progress barsys.stdout.write("\r[%s%s] %d%%" % ('█' * progress, '  ' * (50 - progress), progress * 2))sys.stdout.flush()class CrawlSelenium:def __init__(self, explorer="Chrome", url="https://www.google.com"):self.url = urlself.explorer = explorerdef set_loading_strategy(self, strategy="normal"):self.options = Options()self.options.page_load_strategy = strategydef crawl(self):# instantiate driver according to corresponding explorerif self.explorer == "Chrome":self.driver = webdriver.Chrome(options=self.options)if self.explorer == "Opera":self.driver = webdriver.Opera(options=self.options)if self.explorer == "Firefox":self.driver = webdriver.Firefox(options=self.options)if self.explorer == "Edge":self.driver = webdriver.Edge(options=self.options)# search on google# navigate to urlself.driver.get(self.url)# locate input fieldsearch_input = self.driver.find_element(By.NAME, 'q')# emulate user input and enter to searchwebdriver.ActionChains(self.driver).move_to_element(search_input).send_keys("pokemon" + Keys.ENTER).perform()# navigate to google image# find navigation buttonsself.driver.find_element(By.LINK_TEXT, '图片').click()# load more images as many as possible# scrolling to bottomself.driver.execute_script("window.scrollTo(0, document.body.scrollHeight)")# get buttonshow_more_button = self.driver.find_element(By.CSS_SELECTOR, "input[value='显示更多搜索结果']")try:while True:# do according to messagemessage = self.driver.find_element(By.CSS_SELECTOR, 'div.OuJzKb.Bqq24e').get_attribute('textContent')# print(message)if message == '正在加载更多内容,请稍候':self.driver.execute_script("window.scrollTo(0, document.body.scrollHeight)")elif message == '新内容已成功加载。向下滚动即可查看更多内容。':# scrolling to bottomself.driver.execute_script("window.scrollTo(0, document.body.scrollHeight)")if show_more_button.is_displayed():show_more_button.click()elif message == '看来您已经看完了所有内容':breakelif message == '无法加载更多内容,点击即可重试。':show_more_button.click()else:self.driver.execute_script("window.scrollTo(0, document.body.scrollHeight)")except Exception as err:print(err)# find all image elements in google image result pageimgs = self.driver.find_elements(By.CSS_SELECTOR, "img.rg_i.Q4LuWd")img_count = 0for img in imgs:try:# image per secondtime.sleep(1)print('\ndownloading image ' + str(img_count) + ': ')img_url = img.get_attribute("src")if img_url == None:continuepath = os.path.join(imgs_dir, str(img_count) + "_img.jpg")request.urlretrieve(url = img_url, filename = path, reporthook = progress_callback, data = None)img_count = img_count + 1except error.HTTPError as http_err:print(http_err)except Exception as err:print(err)def main():# settingcrawl_s = CrawlSelenium(explorer, url)crawl_s.set_loading_strategy("normal")# make directoryif not os.path.exists(imgs_dir):os.mkdir(imgs_dir)# crawlingcrawl_s.crawl()if __name__ == "__main__":main()

结果

Python爬虫爬取Google图片 -续- :使用Selenium进行网页操作相关推荐

  1. Python爬虫爬取Google图片

    文章目录 urllib urllib.request.urlretrieve urllib3 in python3 PoolManager Request BeautifulSoup 安装 Insta ...

  2. python爬虫,爬取下载图片

    python爬虫,爬取下载图片 分别引入以下三个包 from urllib.request import urlopen from bs4 import BeautifulSoup import re ...

  3. Python爬虫爬取相关图片

    简要的实现实现Python爬虫爬取百度贴吧页面上的图片,下面的网页就是本篇博客所要爬的网页,当然看到的只是其中的一部分图片,是所要爬取的页面, 而下图则是最终的爬取的图片: 接下来就简要的讲讲爬取的整 ...

  4. python爬虫爬取百度图片总结_python爬虫如何批量爬取百度图片

    当我们想要获取百度图片的时候,面对一张张图片,一次次的点击右键下载十分麻烦.python爬虫可以实现批量下载,根据我们下载网站位置.图片位置.图片下载数量.图片下载位置等需求进行批量下载,本文演示py ...

  5. python爬虫爬取百度图片,python爬虫篇2:爬取百度图片

    入门级 import requests import re import os from urllib import error def main(): dirPath = "E:\pyth ...

  6. 利用python爬虫爬取斗鱼图片(简单详细)

    关于 在一个安静的夜晚,我缓慢的打开了电脑,望着已经睡着的父母,我轻轻的把门关上,看着斗鱼颜值主播的魅力,我不尽感叹,要是每天都可以不需要那么麻烦的去看那该有多好! 于是我想起了最近刚学的爬虫,嘴角露 ...

  7. Python爬虫爬取src图片

    Python爬虫爬取图片 需要用到的库: os time request lxml 代码源码如下: import os import time import requests from lxml im ...

  8. 超详细解析python爬虫爬取京东图片

    超详细图片爬虫实战 实例讲解(京东商城手机图片爬取) 1.创建一个文件夹来存放你爬取的图片 2.第一部分代码分析 3.第二部分代码分析 完整的代码如下所示: 升级版代码: 爬取过程中首先你需要观察在手 ...

  9. python爬虫爬取4K图片实例

    爬取目标网站https://pic.netbian.com/4kfengjing/index.html 之前写的时候发现爬取的图片都是缩略图,不是原图4k的,经过改良得以实现 思路: 话不多说,详细思 ...

  10. 使用python爬虫爬取搜狗图片无法获得图片网址

    错误原因 找页面网址时:我是打开一张图片,从上方搜索栏复制的,然后发现了规律 xxxx#did=0 这个0一直往后增加,我把它作为页面规律.试验了一下,这些网址能进入到对应的图片. 然后打开了F12, ...

最新文章

  1. Golang向Templates 插入对象的值
  2. 分布式Matlab计算集群建立方法与Demo
  3. C 免费窗体控件Krypton Toolkit 4 2 0的使用
  4. 化妆品包装新趋势|视觉模型样机包装模板,让你茅塞顿开
  5. 【转】摩托罗拉推开源硬件平台计划Project Ara
  6. @程序员,不要再锤产品经理了,锤这个吧!!!
  7. (一)office文档操作之excel表格模板填充数据导出
  8. ios 请在设置中打开相机权限_ios开发相机权限问题
  9. Mac上批量修改文件的编码格式
  10. HDU:2055 An easy problem
  11. 数据库原理(三):Sql Server操作语句
  12. 想要彻底掌握placement各种技巧,这个一定可以如你所愿
  13. 华院计算|切比雪夫,他带起了俄罗斯现代数学的发展
  14. vscode html注释快捷键_最强编辑器 VSCode 系列之插件推荐【不定期更新】
  15. AGV的地图管理,wcs调度系统,wms系统。
  16. Office2021与mathtype7.4兼容问题_1_Office2021(尤其是word2021)与mathtype7组合出现点击mathtype选项后word卡顿并闪退解决方法
  17. 手把手的教你在windows上安装cygwin教程以及验证是否安装成功
  18. Chrome浏览器地址栏配置二维码自动生成工具
  19. python讲师招聘天津_SiKi学院Python人工智能讲师招聘
  20. 如何使用纯JavaScript隐藏DOM元素

热门文章

  1. GPRS附着,PDP激活失败
  2. 多任务学习(Multi-Task Learning)
  3. Android日历操作
  4. 人生苦难重重,如何解决人生的问题?| 读《少有人走的路:心智成熟的旅程》
  5. 新浪微博客户端开发之发布微博,Android面试题
  6. CumtCTF第二次双月赛Writeup(Web详解)
  7. pandas_计算年化收益率
  8. ThinkPHP5在线问答系统
  9. Matrix Concatenate 矩阵串联
  10. 基于安卓Android平台的数独游戏的开发