文章目录

  • 写在前面:
  • 目标
  • 网页分析
  • 代码编辑
  • 源码
  • 写在后面

写在前面:

算算学习爬虫断断续续的大概有两个月左右了, 从开始的一无所知 ,到后面能爬点简单的网站,真的是满满的一把辛酸泪. 如今马上期末考,想了想我没看过的网课…决定先放一放,恰好最近爬取了彼岸图网的图片, 决定写一篇博客作为这段时间学习的总结. 希望能有像本小白刚开始一样懵逼的新小白们参考的一点点价值, 也希望有大佬对不足或者能改进的地方提出建议, 不胜感激.

目标

彼岸图网的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像素预览图相关推荐

  1. 程序猿必备福利之二上篇!!!简易使用Nodejs实现从美图网爬取清晰脱俗的美图???

    当然这里为了能够让小白也能够看懂学会,我会说的很详细,我很体谅小白的哦,分了几篇讲解,请谅解哦 这里先来一波看前美图福利,激起你的学习欲望,嘿嘿嘿!!!点击查看程序猿必备福利之二下篇##### 小白如 ...

  2. python爬虫之-斗图网爬取

     python爬虫之-斗图啦爬取 利用:requests, re 功能:用户自定义关键词,页码 整体代码 # 请求库 import requests # 正则 import re # 让用户输入 im ...

  3. Python 网络爬虫:爬取4K高清美图

    爬取4K高清美图 这篇爬虫主要是用来爬取网站高清4K图片,这也是笔者学初学爬虫的时候最先写一个的爬虫脚本,现在回过头来重新梳理一下,也算是对从前知识的一个总结,希望对大家有所帮助! 文章目录 爬取4K ...

  4. Python实现多线程批量下载昵图网的清晰预览图

    我入门Python编程的一个习作:Python多线程下载昵图网的清晰预览图. 目前昵图网(nipic.com)没有限制爬虫,可以用requests来快速打开页面和下载图片. 注意:本文只是示范多线程下 ...

  5. Python爬虫——片库网 爬取 视频

    片库url:http://tv.cnco.me/ 一.进入网站 二.输入关键字跳转界面 格式: url = "http://tv.cnco.me/" search_keyword ...

  6. python诗词名句网爬取《三国演义》

    import requests import reheaders = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWe ...

  7. 如何生成IStyleGalleryItem和ISymbol对象的预览图(转载)

    http://blog.csdn.net/giselite/article/details/8451877 来看一下ArcMap的符号选择器: ArcMap的符号选择器都提供了符号的预览图,另一个预览 ...

  8. [网络爬虫|smtp协议|python]东方财富网爬虫,python smtp协议发送爬取数据至QQ邮箱

    本文改自 [网络爬虫|smtp协议|python]东方财富网爬虫,python smtp协议发送爬取数据至QQ邮箱 之前写的爬虫单子,代码已经跑了快3个月了,后续又增加了一些需求,修改了一些小bug ...

  9. python抓取文献关键信息,python爬虫——使用selenium爬取知网文献相关信息

    python爬虫--使用selenium爬取知网文献相关信息 写在前面: 本文章限于交流讨论,请不要使用文章的代码去攻击别人的服务器 如侵权联系作者删除 文中的错误已经修改过来了,谢谢各位爬友指出错误 ...

最新文章

  1. hdu 2879【留坑】
  2. Java.math包中常用的类
  3. 13 | 答疑(一):无法模拟出 RES 中断的问题,怎么办?
  4. android 使用photoshop 裁剪图片
  5. 开源 免费 java CMS - FreeCMS1.7 栏目管理
  6. max file descriptors [4096] for elasticsearch process is too low, increase to at least [65535]
  7. TFLite基础知识
  8. java经纬度排序,elasticsearch搜索经纬度(lbs)_geo_distance距离排序实现方案
  9. android仿微信红包动画,Android仿微信打开红包动画(逐帧动画)
  10. Java中文件File
  11. bin文件夹是个什么东西?
  12. Debian10更换软件源
  13. 【mac 环境】邮箱密码修改后,foxmail无法正常接收邮件
  14. Typroa导出HTML带大纲
  15. 光交换机配置与维护常用命令
  16. 第27篇 联盟链 + metamask + remix 玩转智能合约
  17. python起笔落笔__怎样在python里让海龟画图抬笔落笔?
  18. Arcgis小技巧【12】——ArcGIS标注的各种用法和示例
  19. 五年级上学期学生期末评语
  20. Uva 101 the block problem 木块问题(算法竞赛经典入门)STL vector

热门文章

  1. 大学计算机基础第二版期末试题,大学计算机基础考试试题
  2. 微信公众号开发之语音消息识别
  3. jQuery(JS库) | 一文带你掌握jQuery的使用
  4. MFC绘制有理柱面和圆锥面
  5. 数据库扩容也可以如此丝滑,MySQL千亿级数据生产环境扩容实战
  6. 鼠标跨屏操作(无需添加外设)-- Mouse without Borders
  7. java中MVC原理详解,Spring MVC 原理总结
  8. js实现淡入淡出轮播图
  9. 常用计算机设备教案,初中信息技术《导购电脑设备》教案
  10. 十五、商城 - 品牌管理-AngularJS(3)