Python爬虫爬取Google图片 -续- :使用Selenium进行网页操作
文章目录
- 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
,对于 Java
,Ruby
等也有相关的实现,可以实现远程控制浏览器并模拟用户和模拟器的交互操作。
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
模拟 shift
,ctrl
,alt
的按键效果,例如 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_down
和 key_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
通过 ActionChains1
的 drag_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进行网页操作相关推荐
- Python爬虫爬取Google图片
文章目录 urllib urllib.request.urlretrieve urllib3 in python3 PoolManager Request BeautifulSoup 安装 Insta ...
- python爬虫,爬取下载图片
python爬虫,爬取下载图片 分别引入以下三个包 from urllib.request import urlopen from bs4 import BeautifulSoup import re ...
- Python爬虫爬取相关图片
简要的实现实现Python爬虫爬取百度贴吧页面上的图片,下面的网页就是本篇博客所要爬的网页,当然看到的只是其中的一部分图片,是所要爬取的页面, 而下图则是最终的爬取的图片: 接下来就简要的讲讲爬取的整 ...
- python爬虫爬取百度图片总结_python爬虫如何批量爬取百度图片
当我们想要获取百度图片的时候,面对一张张图片,一次次的点击右键下载十分麻烦.python爬虫可以实现批量下载,根据我们下载网站位置.图片位置.图片下载数量.图片下载位置等需求进行批量下载,本文演示py ...
- python爬虫爬取百度图片,python爬虫篇2:爬取百度图片
入门级 import requests import re import os from urllib import error def main(): dirPath = "E:\pyth ...
- 利用python爬虫爬取斗鱼图片(简单详细)
关于 在一个安静的夜晚,我缓慢的打开了电脑,望着已经睡着的父母,我轻轻的把门关上,看着斗鱼颜值主播的魅力,我不尽感叹,要是每天都可以不需要那么麻烦的去看那该有多好! 于是我想起了最近刚学的爬虫,嘴角露 ...
- Python爬虫爬取src图片
Python爬虫爬取图片 需要用到的库: os time request lxml 代码源码如下: import os import time import requests from lxml im ...
- 超详细解析python爬虫爬取京东图片
超详细图片爬虫实战 实例讲解(京东商城手机图片爬取) 1.创建一个文件夹来存放你爬取的图片 2.第一部分代码分析 3.第二部分代码分析 完整的代码如下所示: 升级版代码: 爬取过程中首先你需要观察在手 ...
- python爬虫爬取4K图片实例
爬取目标网站https://pic.netbian.com/4kfengjing/index.html 之前写的时候发现爬取的图片都是缩略图,不是原图4k的,经过改良得以实现 思路: 话不多说,详细思 ...
- 使用python爬虫爬取搜狗图片无法获得图片网址
错误原因 找页面网址时:我是打开一张图片,从上方搜索栏复制的,然后发现了规律 xxxx#did=0 这个0一直往后增加,我把它作为页面规律.试验了一下,这些网址能进入到对应的图片. 然后打开了F12, ...
最新文章
- Golang向Templates 插入对象的值
- 分布式Matlab计算集群建立方法与Demo
- C 免费窗体控件Krypton Toolkit 4 2 0的使用
- 化妆品包装新趋势|视觉模型样机包装模板,让你茅塞顿开
- 【转】摩托罗拉推开源硬件平台计划Project Ara
- @程序员,不要再锤产品经理了,锤这个吧!!!
- (一)office文档操作之excel表格模板填充数据导出
- ios 请在设置中打开相机权限_ios开发相机权限问题
- Mac上批量修改文件的编码格式
- HDU:2055 An easy problem
- 数据库原理(三):Sql Server操作语句
- 想要彻底掌握placement各种技巧,这个一定可以如你所愿
- 华院计算|切比雪夫,他带起了俄罗斯现代数学的发展
- vscode html注释快捷键_最强编辑器 VSCode 系列之插件推荐【不定期更新】
- AGV的地图管理,wcs调度系统,wms系统。
- Office2021与mathtype7.4兼容问题_1_Office2021(尤其是word2021)与mathtype7组合出现点击mathtype选项后word卡顿并闪退解决方法
- 手把手的教你在windows上安装cygwin教程以及验证是否安装成功
- Chrome浏览器地址栏配置二维码自动生成工具
- python讲师招聘天津_SiKi学院Python人工智能讲师招聘
- 如何使用纯JavaScript隐藏DOM元素