python彼岸图网爬取1200像素预览图
文章目录
- 写在前面:
- 目标
- 网页分析
- 代码编辑
- 源码
- 写在后面
写在前面:
算算学习爬虫断断续续的大概有两个月左右了, 从开始的一无所知 ,到后面能爬点简单的网站,真的是满满的一把辛酸泪. 如今马上期末考,想了想我没看过的网课…决定先放一放,恰好最近爬取了彼岸图网的图片, 决定写一篇博客作为这段时间学习的总结. 希望能有像本小白刚开始一样懵逼的新小白们参考的一点点价值, 也希望有大佬对不足或者能改进的地方提出建议, 不胜感激.
目标
彼岸图网的4K图显然不是本小白能驾驭的了的, 但观察发现,每一页的展示页面中的图片有1200像素, 还算可以. 于是决定爬取这个. 浏览网站发现,在4K壁纸分类下质量较好, 决定爬取这一部分的图片.
分类
展示页面:
直接另存为的图片信息:
网页分析
彼岸图网对于爬虫还是很友好的,没有动态加载,ip限制等反扒措施,只需要一个浏览器信息就OK了.
网页逻辑也很简单, 大体就是 分类 → 分页 → 图片
了解这些之后, 就可以动手写了
代码编辑
总体思路:
访问分类页面→获取总页数,构建每一页的url→多线程分别访问每一页→
每一页访问每张图片的地址→保存图片
编辑
先导入本次用到的包
import requests
from bs4 import BeautifulSoup
import time
import datetime
import os
import sys
import threading
按照代码运行逻辑讲解,写个主函数: 这里就花里胡哨一下,本质是获取url地址和user-agent
if __name__ == '__main__':print('彼岸图网图片爬取'.center(25,'-'))#获取目标地址print('目标地址形如: http://pic.netbian.com/4kdongman/')url = input('请输入目标地址: ')if url == '':url = 'http://pic.netbian.com/4kdongman/'else:pass#简单定义一下默认爬取动漫分类#传入浏览器信息headers = {"user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.138 Safari/537.36"}
然后我需要一个保存的地址, 为了显示的整洁一点,我决定保存到D盘的单独一个文件夹里,并且以分类和爬取日期作为某一分类的保存地址:
current_time = time.localtime() # 获取当前时间,输出开始,结束时间,创建当天文件夹#创建文件夹adress = mak_dir(url,current_time=current_time)[0]path = mak_dir(url,current_time=current_time)[1]
其中mak_dir是自行书写的函数,代码如下:
def mak_dir(url,current_time):#解析url地址,并传入时间try:adress = url.split('/')[-2] #拿出所请求地址的类别,主要用于后续构造urlpath = 'D:\\picture\\' + adress + str(time.strftime('%m-%d', current_time))#设置保存地址#判断改地址是否存在,存在则创建,不存在则跳过folder_1 = os.path.exists('D:\\picture')if not folder_1:os.mkdir('D:\\picture')else:passfolder = os.path.exists(path)if not folder:os.mkdir(path)else:pass#这个地方连用两个if-else结构属无奈之举,因为疑似D盘下无picture文件会报错, 若有更简洁写法敬请于评论区指出return adress,path#返回adress及pathexcept :#捕捉错误网址print('请检查网址!')os.system('pause')#暂停程序restart_program()#调用重启模块,下文会提到
回归主程序,前段仍是花里胡哨, 主要是获取子页面的链接:
start = time.perf_counter() # 计时器print('开始爬取'.center(25,'-'))print('获取目标网址中...')url_allpage_List = get_allpage_url(url)#自定义函数,主要用来获取子页面的所有链接
其中get_allpage_url()函数为:
def get_allpage_url(url):try:url_second_List = [url]#构建子链接列表,传入的而url本身就是第一页的urlhtml = requests.get(url, headers=headers).contentsoup = BeautifulSoup(html, 'html.parser')all_page = eval(soup.select_one('#main > div.page > span.slh + a').text)#选取总页数for item in range(2,all_page+1):#遍历,构建每一页的url地址并存入列表second_url = 'http://pic.netbian.com/' + adress +'/index_' + str(item) + '.html'url_second_List.append(second_url)print('获取网址成功!共{}页'.format(all_page))return url_second_Listexcept :#捕捉错误print('网址有误,请检查!')os.system('pause')restart_program()#自定义重启函数
回归主函数, 执行到此,我们获取了该分类下的所有子页面的链接,并以列表形式存储,现在只需要遍历,并访问每一页即可:
#创建线程池threads = []for url2 in url_allpage_List:#自定义函数save_page()主要用来保存整张页面的图片t = threading.Thread(target=save_page,args=(url2,))#target: 要启动的函数名 args: 参数,多个参数用逗号分割,元组或列表类型threads.append(t)#加入线程池#启动线程并限制最大线程数
这个本质还是遍历了列表, 并执行了函数save_page(),该函数定义为下:
def save_page(url):#保存整个页面html = requests.get(url, headers=headers).contentsoup = BeautifulSoup(html,'html.parser')li = soup.select('#main > div.slist > ul > li')#每一个li标签都是一张图片,遍历liimg_thread = []for item in li:clear = requests.get('http://pic.netbian.com' + item.select_one('a')['href'],headers=headers).content#请求他的重定向地址soup2 = BeautifulSoup(clear,'html.parser')#拿到图片的url地址以及图片的名称img_url = soup2.select_one('#img > img')['src']img_name = str(soup2.select_one('#img > img')['alt'])save_img(img_url,img_name)#自定义函数,下文提到,主要用来保存每一张图片# t = threading.Thread(target=save_img,args=(img_url,img_name))# img_thread.append(t)# for item in img_thread:# item.start()# for item in img_thread:# item.join()#注释部分为多进程形式,但是疑似瞬间发起大量请求会导致主机无响应,请读者自测(将save_img(img_url,img_name)注释,并取消多行注释)current_page = soup.select_one('#main > div.page > b').textprint('第{}/{}页保存成功!'.format(current_page,len(url_allpage_List)))#这两行输出保存页信息
其中涉及到的每一张图片的保存函数,save_img()代码如下:
def save_img(url,name):##将括号内的图片地址保存,并以name命名try:img = requests.get('http://pic.netbian.com' + url,headers=headers).contentimg_name = path + '\\' + name + '.jpg'with open (img_name,'wb') as save_object:#二进制形式打开文件,保存save_object.write(img)except Exception as e:#有极少的图片会处于未知原因报错,鉴于实在太少而且大多有相同图片已保存,就直接pass掉print(e)pass
至此,额外函数均已完成,回归主函数, 仍是花里胡哨,主要在于前几句,启动进程并限制最大进程数为20,并等待所有进程结束后输出爬取完成:
count = 0#计数for item in threads:item.start()#启动进程count += 1print('第{}/{}号进程启动...'.format(count,len(url_allpage_List)))while True:if (len(threading.enumerate()) < 20):#限制最大进程数breakfor item in threads:#等待所有进程结束item.join()print('爬取完成'.center(25,'-'))end = time.perf_counter()spent_time = datetime.timedelta(seconds=end - start)#所耗费时间,datatime的timedelta可以将秒数转换为00:00:00的形式print('共用时: {}'.format(spent_time))#输出结束时间print('开始时间为: 北京时间' + time.strftime('%Y-%m-%d %H:%M:%S', current_time))current_time_end = time.localtime()print('结束时间为: 北京时间' + time.strftime('%Y-%m-%d %H:%M:%S', current_time_end))os.system('pause')#等待restart_program()#重启
补充:
实际自行编写代码时,反而是按照程序执行的反方向编写更加思路清晰.
效果:
源码
# -- coding: gbk --
import requests
from bs4 import BeautifulSoup
import time
import datetime
import os
import sys
import threadingdef restart_program():#自启模块python = sys.executableos.execl(python, python, *sys.argv)def mak_dir(url,current_time):#解析url地址,并传入时间try:adress = url.split('/')[-2] #拿出所请求地址的类别path = 'D:\\picture\\' + adress + str(time.strftime('%m-%d', current_time))#设置地址#判断改地址是否存在,存在则创建,不存在则跳过folder_1 = os.path.exists('D:\\picture')if not folder_1:os.mkdir('D:\\picture')else:passfolder = os.path.exists(path)if not folder:os.mkdir(path)else:passreturn adress,path#返回adress及pathexcept :#捕捉错误网址print('请检查网址!')os.system('pause')#暂停程序restart_program()#调用重启模块def get_allpage_url(url):try:url_second_List = [url]#传入的url本身就是第一页的urlhtml = requests.get(url, headers=headers).contentsoup = BeautifulSoup(html, 'html.parser')all_page = eval(soup.select_one('#main > div.page > span.slh + a').text)#选取总页数for item in range(2,all_page+1):#遍历,构建每一页的url地址并存入列表second_url = 'http://pic.netbian.com/' + adress +'/index_' + str(item) + '.html'url_second_List.append(second_url)print('获取网址成功!共{}页'.format(all_page))return url_second_Listexcept :#捕捉错误print('网址有误,请检查!')os.system('pause')restart_program()def save_page(url):#保存整个页面html = requests.get(url, headers=headers).contentsoup = BeautifulSoup(html,'html.parser')li = soup.select('#main > div.slist > ul > li')#每一个li标签都是一张图片,遍历liimg_thread = []for item in li:clear = requests.get('http://pic.netbian.com' + item.select_one('a')['href'],headers=headers).content#请求他的重定向地址soup2 = BeautifulSoup(clear,'html.parser')#拿到图片的url地址以及图片的名称img_url = soup2.select_one('#img > img')['src']img_name = str(soup2.select_one('#img > img')['alt'])save_img(img_url,img_name)# t = threading.Thread(target=save_img,args=(img_url,img_name))# img_thread.append(t)# for item in img_thread:# item.start()# for item in img_thread:# item.join()#注释部分为多进程形式,但是疑似瞬间发起大量请求会导致主机无响应,请读者自测(将save_img(img_url,img_name)注释,并取消多行注释)current_page = soup.select_one('#main > div.page > b').textprint('第{}/{}页保存成功!'.format(current_page,len(url_allpage_List)))#这两行输出保存页信息def save_img(url,name):#将括号内的图片地址保存,并name命名try:img = requests.get('http://pic.netbian.com' + url,headers=headers).contentimg_name = path + '\\' + name + '.jpg'with open (img_name,'wb') as save_object:#二进制形式打开文件,保存save_object.write(img)except Exception as e:#有极少的图片会处于未知原因报错,鉴于实在太少而且大多有相同图片已保存,就直接pass掉print(e)passif __name__ == '__main__':print('彼岸图网图片爬取'.center(25,'-'))#获取目标地址print('目标地址形如: http://pic.netbian.com/4kdongman/')url = input('请输入目标地址: ')if url == '':url = 'http://pic.netbian.com/4kdongman/'else:pass#简单定义一下默认爬取动漫分类headers = {"user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.138 Safari/537.36"}current_time = time.localtime() # 获取当前时间,输出开始,结束时间,创建当天文件夹#创建文件夹adress = mak_dir(url,current_time=current_time)[0]path = mak_dir(url,current_time=current_time)[1]start = time.perf_counter() # 计时器print('开始爬取'.center(25,'-'))print('获取目标网址中...')url_allpage_List = get_allpage_url(url)#获取子页面的所有链接#创建线程池threads = []for url2 in url_allpage_List:t = threading.Thread(target=save_page,args=(url2,))#target: 要启动的函数名 args: 参数,多个参数用逗号分割,元组或列表类型threads.append(t)#加入线程池#启动线程并限制最大线程数count = 0#计数for item in threads:item.start()#启动进程count += 1print('第{}/{}号进程启动...'.format(count,len(url_allpage_List)))while True:if (len(threading.enumerate()) < 20):#限制最大进程数breakfor item in threads:#等待所有进程结束item.join()print('爬取完成'.center(25,'-'))end = time.perf_counter()spent_time = datetime.timedelta(seconds=end - start)#所耗费时间,datatime的timedelta可以将秒数转换为00:00:00的形式print('共用时: {}'.format(spent_time))#输出结束时间print('开始时间为: 北京时间' + time.strftime('%Y-%m-%d %H:%M:%S', current_time))current_time_end = time.localtime()print('结束时间为: 北京时间' + time.strftime('%Y-%m-%d %H:%M:%S', current_time_end))os.system('pause')#等待restart_program()#重启
写在后面
- 有尝试easygui库编写GUI面板,但是打包好后会闪退, 而且每两个页面呈关闭打开的交换状态, 鉴于考试在即, 于是没有深究. 若有良好的解决方案, 敬请告知.
- 第一篇博客, 作为对近段学习的总结,有不妥之处,还望海涵.
- 感谢阅读.
python彼岸图网爬取1200像素预览图相关推荐
- 程序猿必备福利之二上篇!!!简易使用Nodejs实现从美图网爬取清晰脱俗的美图???
当然这里为了能够让小白也能够看懂学会,我会说的很详细,我很体谅小白的哦,分了几篇讲解,请谅解哦 这里先来一波看前美图福利,激起你的学习欲望,嘿嘿嘿!!!点击查看程序猿必备福利之二下篇##### 小白如 ...
- python爬虫之-斗图网爬取
python爬虫之-斗图啦爬取 利用:requests, re 功能:用户自定义关键词,页码 整体代码 # 请求库 import requests # 正则 import re # 让用户输入 im ...
- Python 网络爬虫:爬取4K高清美图
爬取4K高清美图 这篇爬虫主要是用来爬取网站高清4K图片,这也是笔者学初学爬虫的时候最先写一个的爬虫脚本,现在回过头来重新梳理一下,也算是对从前知识的一个总结,希望对大家有所帮助! 文章目录 爬取4K ...
- Python实现多线程批量下载昵图网的清晰预览图
我入门Python编程的一个习作:Python多线程下载昵图网的清晰预览图. 目前昵图网(nipic.com)没有限制爬虫,可以用requests来快速打开页面和下载图片. 注意:本文只是示范多线程下 ...
- Python爬虫——片库网 爬取 视频
片库url:http://tv.cnco.me/ 一.进入网站 二.输入关键字跳转界面 格式: url = "http://tv.cnco.me/" search_keyword ...
- python诗词名句网爬取《三国演义》
import requests import reheaders = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWe ...
- 如何生成IStyleGalleryItem和ISymbol对象的预览图(转载)
http://blog.csdn.net/giselite/article/details/8451877 来看一下ArcMap的符号选择器: ArcMap的符号选择器都提供了符号的预览图,另一个预览 ...
- [网络爬虫|smtp协议|python]东方财富网爬虫,python smtp协议发送爬取数据至QQ邮箱
本文改自 [网络爬虫|smtp协议|python]东方财富网爬虫,python smtp协议发送爬取数据至QQ邮箱 之前写的爬虫单子,代码已经跑了快3个月了,后续又增加了一些需求,修改了一些小bug ...
- python抓取文献关键信息,python爬虫——使用selenium爬取知网文献相关信息
python爬虫--使用selenium爬取知网文献相关信息 写在前面: 本文章限于交流讨论,请不要使用文章的代码去攻击别人的服务器 如侵权联系作者删除 文中的错误已经修改过来了,谢谢各位爬友指出错误 ...
最新文章
- hdu 2879【留坑】
- Java.math包中常用的类
- 13 | 答疑(一):无法模拟出 RES 中断的问题,怎么办?
- android 使用photoshop 裁剪图片
- 开源 免费 java CMS - FreeCMS1.7 栏目管理
- max file descriptors [4096] for elasticsearch process is too low, increase to at least [65535]
- TFLite基础知识
- java经纬度排序,elasticsearch搜索经纬度(lbs)_geo_distance距离排序实现方案
- android仿微信红包动画,Android仿微信打开红包动画(逐帧动画)
- Java中文件File
- bin文件夹是个什么东西?
- Debian10更换软件源
- 【mac 环境】邮箱密码修改后,foxmail无法正常接收邮件
- Typroa导出HTML带大纲
- 光交换机配置与维护常用命令
- 第27篇 联盟链 + metamask + remix 玩转智能合约
- python起笔落笔__怎样在python里让海龟画图抬笔落笔?
- Arcgis小技巧【12】——ArcGIS标注的各种用法和示例
- 五年级上学期学生期末评语
- Uva 101 the block problem 木块问题(算法竞赛经典入门)STL vector