思路分享:
1、主页下面是套图名和对应网址,那就只要把套图名和对应网址提取到并放入到一个字典就可以了。如果要爬取多页,只要搞清楚每页的规则,把每页的地址拼接好放到一个列表中,遍历它即可。
2、随便点个套图进去,就套图对应的图片,只要把图片对应的网址提取并放入到列表即可。因为图片都是多页展示,同样拼接每页地址并放入列表中,然后遍历它。
3、下载图片并保存到对应套图名文件夹中。
4、1-3步都定义为函数,方便调取。
思路分析完,那就开干:
做的时候,反着来,先实现下载图片的功能,再实现获取图片地址列表的功能,最后再实现获取套图地址及套图名字典的功能。这样做的话,可以先集中精神实现核心功能,然后再完善它。
具体源代码如下:
[Python] 纯文本查看 复制代码import requests
import os
from lxml import etree
import re
import time
import random
def down_pic(headers:dict[str,str],url:str,name:int,path:str):
"""
下载指定URL的图片并保存。
Args:
headers:请求头。
url:下载图片的URL。
name:图片名称。
path:保存图片的路径。
"""
res = requests.get(url,headers=headers)
img = res.content
pic_path = os.path.join(path,str(name)+'.jpg')
with open(pic_path,'wb') as f:
f.write(img)
print(f'图片:{name}.jpg 已下载完成……')
def get_pic_urls(headers:dict[str,str],url:str):
"""
通过主题地址获取主题对应所有图片的地址。
Args:
headers:请求头。
url:主题图片(套图)的URL。
Returns:
pic_urls:图片地址的列表。
"""
# 获取页码数
res = requests.get(url, headers=headers)
res.encoding = 'gbk'
html = res.text
parser = etree.HTML(html)
pages_xpath = r'//*[@id="pages"]/a[1]/text()'
pages_str = parser.xpath(pages_xpath)[0]
pages_match = re.search(r'\d+',pages_str)
pages = int(pages_match.group())
#拼接获取图片页码网址列表
page_urls = [url]
for i in range(2,pages+1):
page_urls.append(f'{url[:-5]}_{i}.html')
# 获取下载图片网址列表
pic_urls = []
for url in page_urls:
res = requests.get(url,headers=headers)
html = res.text
parser = etree.HTML(html)
urls_xpath = r'/html/body/div[8]/img/@src'
pic_urls += parser.xpath(urls_xpath)
return pic_urls
def get_theme_urls(headers:dict[str,str],url:str,start_page:int,end_page:int):
"""
通过指定页面范围获取对应的主题名称及地址。
Args:
headers:请求头。
url:图片主页的URL。
start_page:开始页码。
end_page:结束页码。
Returns:
theme_urls:主题(套图)地址及名称的字典。
"""
#拼接获取主页页码网址列表
page_urls = []
for i in range(start_page,end_page+1):
page_urls.append(f'{url}/html/list_1_{i}.html')
# 获取主题(套图)网址字典
urls = [] #用来存放主题网址
names = [] #用来存放主题名
for url in page_urls:
res = requests.get(url,headers=headers)
res.encoding = 'gbk'
html = res.text
parser = etree.HTML(html)
urls_xpath = r'//body/div[5]/ul/li/a/@href'
names_xpath = r'//body/div[5]/ul/li/p/a/text()'
urls += parser.xpath(urls_xpath)
names += parser.xpath(names_xpath)
time.sleep(random.random()) #模拟1秒内随机延迟
theme_urls = dict(zip(urls,names))
return theme_urls
def main():
url = 'https://www.774tuba.cc'
headers = {
'user-agent':
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/136.0.0.0 Safari/537.36',
'Referer':url
}
start_page = int(input('请输入起始页:'))
end_page = int(input('请输入结束页:'))
theme_urls = get_theme_urls(headers, url, start_page, end_page)
for theme_url, path in theme_urls.items():
if not os.path.exists(path):
os.makedirs(path)
pic_urls = get_pic_urls(headers, theme_url)
for name, url in enumerate(pic_urls,start=1):
time.sleep(random.random())
down_pic(headers, url, name, path)
if __name__ == '__main__':
main()
注意:起始页和结束页范围不要太大了,不然会运行很久。