方案一
利用urlretrieve()函数链接到 图片url 直接储存图片
urlretrieve是urllib库中的一个函数
urllib库是python的内置包,不需要下载安装
urllib包含了四个模块分别是:
request:基本的http请求模块,用来模拟发送请求。
error:异常处理模块,捕获请求中的异常,然后进行重试或其他的操作以保证程序不会意外终止。
parse:一个根据模块,提供了如拆分、解析、合并等的许多URL处理方法。
robotparser:主要用来识别网站的robots.txt文件,然后判断哪些网站可以爬,哪些不能。
而urlretrieve就在urllib的request模块中。
代码实现:
点击查看代码
from urllib.request import urlretrieve
# img_url为图片链接,
# file_name为文件储存路径及文件名
img_url= 'https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1569317945346&di=0f7ee951fdbe8a9949a491757dfe2141&imgtype=0&src=http%3A%2F%2Fb-ssl.duitang.com%2Fuploads%2Fitem%2F201707%2F24%2F20170724020822_JwihM.jpeg'
file_name = '我的女神周冬雨.jpeg'
#如果没有传入file_name,则urlretrieve会在Temp文件夹中生成一个临时文件。
urlretrieve(img_url, file_name)
方案二
通过requests直接写入图片
requests底层框架使用的是urllib3,整体在语法上相对简单一些
代码实现:
import requests
img_url为图片链接,
file_name为文件储存路径及文件名
img_url= 'https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1569317945346&di=0f7ee951fdbe8a9949a491757dfe2141&imgtype=0&src=http%3A%2F%2Fb-ssl.duitang.com%2Fuploads%2Fitem%2F201707%2F24%2F20170724020822_JwihM.jpeg'
file_name = '我的女神周冬雨.jpeg'
res=requests.get(img_url)
with open(file_name ,'wb') as f:
f.write(res.content)
因为selenium本身是没有下载图片的模块的,所以以上方法还可以和selenium结合使用。
先通过url_path = driver.find_element_by_xpath(path).get_attribute("src")获取图片地址,再调用上诉方法
方案三
利用selenium截图获取图片
和上面两种方法不同的是,这种方法主要是为了针对反爬(例如由无数小图拼接而成的验证码)而进行的物理手段获取。
代码实现:
from selenium import webdriver
from PIL import Image
from io import BytesIO
img_url为图片链接,
file_name为文件储存路径及文件名,这里注意图片文件必须以 png 格式保存,
如果需要以jpeg的格式保存需逐行写入(类似方案二)
img_url= 'https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1569317945346&di=0f7ee951fdbe8a9949a491757dfe2141&imgtype=0&src=http%3A%2F%2Fb-ssl.duitang.com%2Fuploads%2Fitem%2F201707%2F24%2F20170724020822_JwihM.jpeg'
filename = '女神周冬雨.png'
driver = webdriver.Chrome()
driver.get(img_url)
网页中图片的定位(也可用其他方式定位)
img = driver.find_element_by_tag_name('img')
获取图片位子和宽高
location = img.location
size = img.size
返回左上角和右下角的坐标
top,bottom,left,right = location['y'], location['y']+size['height'], location['x'], location['x']+size['width']
截取整张网页图片
screenshot = driver.get_screenshot_as_png()
screenshot = Image.open(BytesIO(screenshot))
将网页中需要的图片通过坐标裁剪出来
screenshot = screenshot.crop((left, top, right, bottom))
screenshot.save(file_name)
driver.close()
由于是截图,所以舍弃了对图片清晰度的要求,图片会存在一定的失真(验证码图例)
滑块验证码完整项目链接:https://blog.csdn.net/weixin_43715458/article/details/99732804
方案四
这个方法,emmm…就是最原始的物理保存法了,将我们本文开头熟知的操作用脚本模拟实现。
在图片上模拟点击鼠标右键,
然后模拟点击 图片另存为,
在弹出保存窗口中,
模拟选择或输入保存的位置,
模拟点击 确定 按钮即可。
想不到吧?又回到了那个钻木取火的年代!
这个方法需要用到两个非常见库:
pyautogui用于传入键盘指令
pyperclip用于操作剪贴板
这里强调一下,我这里使用的是 win10 系统,由于不同操作系统的快捷键和窗口布局可能不一样,
如果你的计算机是xp、win7、mac、linux或其他操作系统,则需要根据自己的电脑快捷键自行对脚本进行调整。
另外,也有朋友和我反应,他的电脑在执行脚本后,系统不会自动将活动程序切换到selenium浏览器,导致后续的键盘指令没有传递给浏览器,这里有个解决方案是通过模拟alt+tab来切换活动程序。只需要在selenium启动的时候切换一次就可以了
点击查看代码
from selenium.webdriver.common.action_chains import ActionChains
from selenium import webdriver
import pyperclip
import pyautogui
from time import sleep
# img_url为图片链接;
# file_name储存用文件名,这里默认储存位置
# 如果需要指定储存位置,需同样用物理方法在弹出的储存窗口中点击选择路径,
# 这里以保存至桌面为例
img_url= 'https://timgsa.baidu.com/timg?image&quality=80&size=b9999_10000&sec=1569317945346&di=0f7ee951fdbe8a9949a491757dfe2141&imgtype=0&src=http%3A%2F%2Fb-ssl.duitang.com%2Fuploads%2Fitem%2F201707%2F24%2F20170724020822_JwihM.jpeg'
file_name = '我的女神周冬雨.jpeg'
file_path = '桌面'
driver = webdriver.Chrome()
driver.get(img_url)
ele=driver.find_element_by_tag_name('img')
# 移动鼠标至图片然后敲击鼠标右键
# 如果你的电脑不会自动将进程切换至selenium浏览器,可以通过以下命令进行切换活动进程
# pyautogui.hotkey('alt', 'tab')
ActionChains(driver).move_to_element(ele).context_click(ele).perform()
# 执行键盘指令时,必须保证此刻的活动任务是selenium的浏览器
# 然后敲击 V 图片另存为(v)的快捷键是V
pyautogui.typewrite('v')
# 单击图片另存之后等1s输入文件名
sleep(1)
# 将文件名传给剪贴板
pyperclip.copy(file_name)
# ctrl + v 粘贴文件名
pyautogui.hotkey('ctrl', 'v')
#下面4行代码是设置文件路径,输完文件名后按6下TAB切到路径栏,
pyautogui.typewrite(['tab','tab','tab','tab','tab','tab','enter'])
pyperclip.copy(file_path)
pyautogui.hotkey('ctrl', 'v')
pyautogui.typewrite(['enter'])
# alt + s 保存
pyautogui.hotkey('alt', 's')
driver.close()