基于Python下载网络图片方法汇总代码实例


Posted in Python onJune 24, 2020

本文介绍下载python下载网络图片的方法,包括通过图片url直接下载、通过re/beautifulSoup解析html下载以及对动态网页的处理等。

通过pic_url单个/批量下载

已知图片url,例如http://xyz.com/series-*(1,2..N).jpg,共N张图片,其链接形式较为固定,这样经简单循环,直接通过`f.write(requests.get(url).content)'即可以二进制形式将图片写入。

import os
import requests

def download(file_path, picture_url):
	headers = {
		"User-Agent": "Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 			(KHTML, like Gecko) Chrome/63.0.3239.132 Safari/537.36 QIHU 360SE",
		}
	r = requests.get(picture_url, headers=headers)
	with open(file_path, 'wb') as f:
		f.write(r.content)

def main():
	os.makedirs('./pic/', exist_ok=True) # 输出目录

	prefix_url = 'http://xyz.com/series-' # 同一类目下的图片url前缀
	n = 6 # 该类目下的图片总数

	tmp = prefix_url.split('/')[-1]
	for i in range(1, n + 1):
		file_path = './pic/' + tmp + str(i) + '.jpg'
		picture_url = prefix_url + str(i) + '.jpg'
		download(file_path, picture_url)
		

if __name__ == '__main__':
	main()

正则re解析html获取pic_url后下载

在实际操作中,图片url按序排列情况较少,多数情况下用户仅知道网页url,需要对当前网页htnl内容进行解析,获取源码中包含的图片url,常用方法有正则表达式匹配或BeautifulSoup等库解析的方法。

正则re解析的思路是:首先通过 requests.get(url).text 获得当前页面html源码;然后通过正则表达式匹配图片url,如 re.compile(r'[a-zA-z]+://[^\s]*\.jpg') 正则式一般会得到.jpg结尾的url,但其他网站图片url可能会以.png或.webp等结尾,甚至需要其他的正则匹配,为此,读者需要对正则表达式有所了解,强烈推荐 正则表达式30分钟入门教程 ;将前一步得到的图片url加入列表,进行下载。

import os
import re
import requests

def get_html(url):
  headers = {
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.97 Safari/537.36 ",
    }
  html = requests.get(url, headers=headers).text

  return html

def parse_html(html_text):
  picre = re.compile(r'[a-zA-z]+://[^\s]*\.jpg') # 本正则式得到.jpg结尾的url
  pic_list = re.findall(picre, html_text)

  return pic_list

def download(file_path, pic_url):
  headers = {
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.97 Safari/537.36 ",
    }
  r = requests.get(pic_url, headers=headers)
  with open(file_path, 'wb') as f:
    f.write(r.content)

def main():
  # 使用时修改url即可
  url = 'http://xyz.com/series'
  html_text = get_html(url)
  pic_list = parse_html(html_text)

  os.makedirs('./pic/', exist_ok=True) # 输出目录
  for pic_url in pic_list:
    file_name = pic_url.split('/')[-1]
    file_path = './pic/' + file_name

    download(file_path, pic_url)
if __name__ == '__main__':
  main()

通过bs4获取pic_url

与正则匹配思路类似,只不过通过Beautiful Soup解析html获得图片url列表,然后依次下载图片。由于各网站html结构有差异,用户需要自行进行适当修改。以下代码是对豆瓣图片的下载。

import os
import time
import requests
from bs4 import BeautifulSoup

def get_html(url):
  headers = {
    'user-agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 			(KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36',
  }
  html = requests.get(url, headers=headers).text

  return html

def parse_html(html_text):
  soup = BeautifulSoup(html_text, 'html.parser')
  li = soup.find_all('div', attrs={'class':'cover'})

  pic_list = []
  for link in li:
    pic_url = link.find('img').get('src')
    pic_url = pic_url.replace('/m/', '/l/')
    pic_list.append(pic_url)

  return pic_list

def download(file_path, pic_url):
  headers = {
    "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.97 Safari/537.36 ",
    }
  r = requests.get(pic_url, headers=headers)
  with open(file_path, 'wb') as f:
    f.write(r.content)

def main():
  '从豆瓣下载石原里美图片,观察发现每页包含30张图片,其url按30递增,如下所示'
  pic_list = []
  for i in range(10):
    url = 'https://movie.douban.com/celebrity/1016930/photos/?type=C&start=' + str(30*i) + '&sortby=like&size=a&subtype=a'
    html_text = get_html(url)
    pic_list += parse_html(html_text)
    
  os.makedirs('./pic/', exist_ok=True) # 输出目录

  for i, pic_url in enumerate(pic_list):
    if i%30 == 0:
      print('正在下载第%s页'%(i/30+1))
    file_name = pic_url.split('/')[-1].split('.')[0] + '.jpg'
    file_path = './pic/' + file_name

    download(file_path, pic_url)

if __name__ == '__main__':
  main()

在下载图片时,发现可以直接访问图片的缩略图url进行下载,但由于豆瓣的反爬策略,直接访问原图url会被服务器拒绝,见下图。解决方法见下一部分。

基于Python下载网络图片方法汇总代码实例

可能遇到的问题

网站反爬虫机制

  • User-Agent:模拟浏览器访问,添加后,服务器会认为是浏览器正常的请求。一般与网页操作相关访问都予以添加。
  • Referer:浏览器以此来判断你从哪一个网页跳转过来。例如在上述豆瓣图片的下载示例中,直接输入网址会被拒绝,但你在网站一步步点击却会在同一地址中得到内容,这就是因为你在一步步访问时是有一个前序跳转地址的,这个地址可以通过“F12”在header中得到,如果找不到的话试一试根目录地址“ movie.douban.com/”,或是前几步的地址”… GitHub仓库'adv_bs4_url.py‘文件 。
  • ip伪装:构建ip池。
  • Cookie伪装:cookie是服务器用来辨别你此时的状态的,每一次向服务器请求cookie都会随之更新。
  • 常用正则式匹配

网页的数据采用异步加载,如js渲染的页面或ajax加载的数据通过get不到完整页面源码。

一种方案是常说的动态爬虫,即采用一些第三方的工具,模拟浏览器的行为加载数据,如Selenium、PhantomJs等。网络上有较多介绍文章,有点麻烦就没有自己写了,后续有需求的话在做吧,不过其他方法已经够用了。

另外可以通过分析页面,找到请求借口,加载页面。其核心就是跟踪页面的交互行为 JS 触发调度,分析出有价值、有意义的核心调用(一般都是通过 JS 发起一个 HTTP 请求),然后我们使用 Python 直接访问逆向到的链接获取价值数据。通过"F12”进行分析,例如对于花瓣网,可以获得其链接为" huaban.com/search/?q=石… request.urlopen(url).read() 读取网页。

基于Python下载网络图片方法汇总代码实例

Pyautogui,鼠标模拟点击的“傻瓜式”流程

本方法仅适用于重复性的工作,而且效率较低,但完全没有被反爬虫策略屏蔽的风险。其核心思想与word中的“宏”类似,就是你告诉计算机一次循环中鼠标分别如何操作,然后让其自动循环。代码简单明了。

import pyautogui
import time

pyautogui.FAILSAFE = True

def get_mouse_positon():
  time.sleep(3) # 此间将鼠标移动到初始位置
  x1, y1 = pyautogui.position()
  print(x1, y1)
  pyautogui.click(x=x1, y=y1, button='right') # 模拟鼠标右键点击,呼出菜单
  time.sleep(5) # 此间将鼠标移动到“save image as...”选项中央
  x2, y2 = pyautogui.position()
  print(x2, y2)
  pyautogui.click(x=x2, y=y2) # 模拟鼠标左键点击,点中“save image as...”
  time.sleep(10) # 此间弹出保存文件弹窗,自行选择保存位置,并将鼠标移至“保存(S)”按钮中央
  x3, y3 = pyautogui.position()
  pyautogui.click(x=x3, y=y3)
  print(x3, y3)


def click_download(N):
  for i in range(N): # 拟下载图片数量
    pyautogui.click(x=517, y=557, duration=0.25, button='right') # 呼出菜单,自行将x/y设置为x1/y1
    time.sleep(1)
    pyautogui.click(x=664, y=773, duration=0.25) # 下载,x/y为x2/y2
    time.sleep(1)
    pyautogui.click(x=745, y=559, duration=0.25) # 保存,x/y为x3/y3
    time.sleep(1)
    pyautogui.click(x=517, y=557, duration=0.25) # 进入下一张图片
    time.sleep(2) # 取决于网络加载速度,自行设置
 if __name__ == "__main__":
  # get_mouse_positon() # 一开始只运行此命令,获取屏幕坐标,后续注释掉该句
  click_download(10)

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
Python中基础的socket编程实战攻略
Jun 01 Python
python flask 多对多表查询功能
Jun 25 Python
python 中random模块的常用方法总结
Jul 08 Python
解决python3中自定义wsgi函数,make_server函数报错的问题
Nov 21 Python
python实现监控某个服务 服务崩溃即发送邮件报告
Jun 21 Python
pycharm 取消默认的右击运行unittest的方法
Nov 29 Python
Python深拷贝与浅拷贝用法实例分析
May 05 Python
简单了解python 邮件模块的使用方法
Jul 24 Python
python实现数据结构中双向循环链表操作的示例
Oct 09 Python
Django启动时找不到mysqlclient问题解决方案
Nov 11 Python
Python爬虫实现selenium处理iframe作用域问题
Jan 27 Python
Python 使用dict实现switch的操作
Apr 07 Python
Python 分布式缓存之Reids数据类型操作详解
Jun 24 #Python
PyTorch中model.zero_grad()和optimizer.zero_grad()用法
Jun 24 #Python
Pytorch实现将模型的所有参数的梯度清0
Jun 24 #Python
你需要学会的8个Python列表技巧
Jun 24 #Python
pytorch实现查看当前学习率
Jun 24 #Python
在pytorch中动态调整优化器的学习率方式
Jun 24 #Python
CentOS 7如何实现定时执行python脚本
Jun 24 #Python
You might like
丧钟首部独立剧集《丧钟:骑士与龙》北美正式开播,场面血腥
2020/04/09 欧美动漫
从php核心代码分析require和include的区别
2011/01/02 PHP
PHP下使用CURL方式POST数据至API接口的代码
2013/02/14 PHP
JavaScript使用cookie
2007/02/02 Javascript
Javascript中replace()小结
2015/09/30 Javascript
Bootstrap每天必学之简单入门
2015/11/19 Javascript
Bootstrap每天必学之表单
2015/11/23 Javascript
jQuery mobile类库使用时加载导航历史的方法简介
2015/12/04 Javascript
js实现仿微博滚动显示信息的效果
2015/12/21 Javascript
Underscore源码分析
2015/12/30 Javascript
JS简单实现无缝滚动效果实例
2016/08/24 Javascript
微信公众号开发 实现点击返回按钮就返回到聊天界面
2016/12/15 Javascript
javascript checkbox/radio onchange不能兼容ie8处理办法
2017/06/13 Javascript
Webpack常见静态资源处理-模块加载器(Loaders)+ExtractTextPlugin插件
2017/06/29 Javascript
Angular项目如何升级至Angular6步骤全纪录
2018/09/03 Javascript
angular.js实现列表orderby排序的方法
2018/10/02 Javascript
解决vue项目本地启动时无法携带cookie的问题
2021/02/06 Vue.js
Python选课系统开发程序
2016/09/02 Python
windows下python之mysqldb模块安装方法
2017/09/07 Python
PyTorch上搭建简单神经网络实现回归和分类的示例
2018/04/28 Python
tensorflow 用矩阵运算替换for循环 用tf.tile而不写for的方法
2018/07/27 Python
Python中collections模块的基本使用教程
2018/12/07 Python
python爬取酷狗音乐排行榜
2019/02/20 Python
HTML5学习笔记之html5与传统html区别
2016/01/06 HTML / CSS
意大利时尚精品店:Nugnes 1920
2020/02/10 全球购物
华为慧通笔试题
2016/04/22 面试题
《特殊的葬礼》教学反思
2014/04/27 职场文书
公务员年终个人总结
2015/02/12 职场文书
2015年科普工作总结
2015/07/23 职场文书
师德师风培训感言
2015/08/03 职场文书
《用字母表示数》教学反思
2016/02/17 职场文书
nginx限制并发连接请求数的方法
2021/04/01 Servers
MySQL 8.0 Online DDL快速加列的相关总结
2021/06/02 MySQL
Ajax实现三级联动效果
2021/10/05 Javascript
Django基础CBV装饰器和中间件
2022/03/22 Python
python自动获取微信公众号最新文章的实现代码
2022/07/15 Python