【爬虫 初出茅庐】 爬取并下载想要图片 源码 分析 + 分享

news/2025/3/14 17:03:33/

先上效果图。
如搜取并下载【鬼灭之刃】和【刀剑神域】相关图片
在这里插入图片描述

在这里插入图片描述

在这里插入图片描述

相关过程分析:

(PS:因为刚学爬虫没几天,若大佬发现有什么问题欢迎指正)

这里爬取的网站是免费提供图片的51贴图。若光爬取单一或者连续网页的图片是很简单的,但是如果要爬取用户输入的指定类型图片呢(如上述的【刀剑神域】),这就需要先找到用户输入串和对应url之间的联系。通过尝试发现,如找【天空之城】,改字符串直接包含在网页的url中:
在这里插入图片描述

那么,第一步:

我们可以将用户输入的串s填入
https://www.51tietu.net/pic/{}/.format(s)
那么就这个url就是我们第一步要爬的网站。不过,由于输入的串有可能是中文,直接丢进askurl函数可能会解码失败,所以要先对读入的串s进行下面操作

s = urllib.parse.quote(s)

这样就可以正常得到网页的html。

第二步:

观察网页的页数和url的关系,如到第二页
在这里插入图片描述发现后缀多了1,那么说明第一页就是/0,第二页/1 。 所以我们在爬取所有页数的时候,只需要控制循环添加url的后缀即可。即第一步部分如下图

 for idx in range(0,num//18 + 6): #num是用户需要的图片数,18是一页的数,后面加6保证能找得到那么多url_tmp = url1 + str(idx)html1 = askurl(url_tmp)soup1 = BeautifulSoup(html1, "html.parser")

第三步:

现在可以矛头指向图片本身了。先F12看封面图是否是我们要找的。在这里插入图片描述
但是发现封面图的链接打开并不是我们要找的原图,而点开封面得到的新网页才有我们的目标图片,但是这时候网页的url似乎又变得无序了起来。
在这里插入图片描述
我们现在离要找的图片的链接只差了一步。就是怎么得到上图的url呢?这时候我们回到前一步,找到前面入口处的对应超链接。(把鼠标移动到标题处即可显示),如图:
在这里插入图片描述
观察这里:href="/p/24998501.html"和前面那张图对比,发现就是后面那个链接https://www.51tietu.net/p/24998501.html的后缀,前面的https://www.51tietu.net/其实就是首页(原谅博主还没学HTML,术语上可能有问题)。那么自然想到,我们只需要爬取要找的图在此的超链接,然后相当于嵌套,变成爬取这个url的信息。那么要找的图的我们已经得到地址了。

最后一步:

最后一步就相当于最简单的爬虫了,爬取img标签下的图片链接即可。然后存入集合中(有可能爬到重复的)。最后,整理一遍思路:
1.先爬取包含s字符串(关键字)的网页
2.找到每个封面对于图片的超链接
3.再对超链接(目标图片的url)进行爬取,找到特定img标签下的链接

那么代码化的话就是一个循环控制页数,把所有超链接存入列表,后面一个循环控制对列表内的每个url进行爬取,再嵌套一个循环找到链接。

(第一次做爬虫,代码可能比较不成熟,望大佬指正)

源代码:

#-*- coding = utf-8 -*-
from bs4 import BeautifulSoup
import re
import urllib.request, urllib.error
import xlwt
import sqlite3
import requests
import osdef main():datalist = getData()download(datalist)findLink = re.compile(r'href="(.*?).html"')
findImg = re.compile(r'src="(.*?)"',re.S)
findTitle = re.compile(r'<h1>(.*?)</h1>')
findRating = re.compile(r'<span class="rating_num" property="v:average">(.*)</span>')
findJudge = re.compile(r'<span>(\d*)人评价</span>')
findInq = re.compile(r'<span class="inq">(.*)</span>')flag = Truedef askurl(url):head = {"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.92 Safari/537.36"}request = urllib.request.Request(url,headers = head)html = ""try:response = urllib.request.urlopen(request)html = response.read().decode("utf-8")except urllib.error.URLError as e:if hasattr(e,"code"):print(e.code)if hasattr(e,"reason"):print(e.reason)flag = Falsereturn htmldef getData():datalist = []html = ""# num = 10s1 = ""s2 = ""s3 = ""s1 = input("输入你想查找图片的人物、角色、番剧名称或者风景等(一个词~)\n")num = eval(input("输入你想下载的图片的数量(0->1k),建议百张以内:\n"))print("====林肯死大头!!====\n")word = s1word = urllib.parse.quote(word)data = []url1 = "https://www.51tietu.net/pic/{}/".format(word)cnt = 0for idx in range(0,num//18 + 6):url_tmp = url1 + str(idx)html1 = askurl(url_tmp)soup1 = BeautifulSoup(html1, "html.parser")temp = str(soup1)for item in soup1.find_all(target="_blank"):item = str(item)for j in re.findall(findLink, item):# j = str(j)data.append(j)cnt += 1print("===以查找到%d张===\n" %cnt)if cnt>=num*3:breakif cnt >= num*3 :breakif cnt>=num*3:breakcnt = 0datalist = set(datalist)print("~~~~~正在缓存图片下载地址,请等待~~~~")for item in data:item = str(item)url = "https://www.51tietu.net{}.html".format(item)html = askurl(url)soup = BeautifulSoup(html,"html.parser")for i in soup.find_all('p'):i = str(i)for j in re.findall(findImg,i):if '.jpg' in str(j) :datalist.add(str(j))cnt += 1if len(datalist)>=num:breakif len(datalist) >= num :breakif len(datalist) >= num :breakdatalist = list(datalist)return datalistdef download(datalist):dir = os.getcwd();  # 当前工作目录。cnt = 1print("··········downloading!(请等待数分钟~) ``````````````")for item in datalist:url = str(item)url.replace('[','')url.replace(']','')url.replace('\\' ,'')#   print(url)urllib.request.urlretrieve(url, dir + '\\result{}.jpg'.format(cnt))  # 下载图片。print("===已下载{}张!可在根目录查看图片下载过程~===\n".format(cnt))cnt += 1print("下载完成,去根目录看看爬取的成果吧~")a = input("===按任意键退出====")main()

http://www.ppmy.cn/news/831928.html

相关文章

剑指 offer 链表算法题:复杂链表的复制

题目描述&#xff1a;输入一个复杂链表&#xff08;每个节点中有节点值&#xff0c;以及两个指针&#xff0c;一个指向下一个节点&#xff0c;另一个特殊指针random指向一个随机节点&#xff09;&#xff0c;请对此链表进行深拷贝&#xff0c;并返回拷贝后的头结点。&#xff0…

Redis Brpop 命令

目录 一、作用二、demo演示 一、作用 Redis Brpop 命令拥有移出并获取list右边的最后一个元素&#xff0c; 如果列表没有元素会阻塞列表直到等待超时或发现可弹出元素为止。 二、demo演示 向 list1 中插入三个元素 a、b、c lpush list1 a b c查看list1中的元素 lrange lis…

AS gradle 添加定制属性,在java里使用

参考 android重新编译res,使用 gradle 在编译时动态设置 Android resValue / BuildConfig / Manifes中<meta-data>变量的值... android {compileSdkVersion project.ext.android.compileSdkVersiondefaultConfig {minSdkVersion project.ext.android.minSdkVersiontarge…

avalon框架系列

之前找工作面试的时候,第一次听说avalon框架,说是可以兼容到IE8,当时就觉得相当厉害. 在入职之后,入职培训就是学习这个框架的内容,初次了解,感觉和Vue框架的语法很像,但是具体之处又有不同. 指令方面很像Vue,比如:ms-for ms-if ms-visible ms-class.... 还有过滤器,avalon框…

[AI系列]langchain

摘要&#xff1a; langchain 源码地址&#xff1a; https://github.com/hwchase17/langchain

Android 高德地图 加载 mbtiles 文件

需要关注的就几个关键点&#xff1a; 1、mbtiles 文件其实就是一个 sqllite 数据库文件。 2、高德sdk 的回调函数 Overridepublic final Tile getTile(int x, int y, int zoom) {byte[] image xxx;return new Tile(TILE_WIDTH, TILE_HEIGHT, image);}3、关键点在于 y 坐标的…

Alvin

Alvin Zhao 東京都 港区虎ノ門&#xff12;&#xff0d;&#xff11;&#xff10;&#xff0d;&#xff14; ホテルオークラ東京 M 663 電話番号: 0335820111 转载于:https://www.cnblogs.com/teamleader/p/4539639.html

avalon

今天用avalon的时候&#xff0c;报了这个错误warning:exception throwed in [avalon.injectBinding] SyntaxError: Unexpected token .(…)原来是ms-click"store_check_all();"中括号里没有参数&#xff0c;改成这样就ok了ms-click"store_check_all(it);" …