Python爬虫爬取美女写真
本帖最后由 szsnk144864 于 2022-5-11 18:49 编辑我有一个朋友告诉我发现一个美女写真网站,要把分类里的图偏爬下来欣赏,
赶巧的是我最近正好在学爬虫,入手搞了一下,只是多线程搞不定
代码仅供参考学习,如造成其它后果请自行负责
import time
import requests
from lxml import etree
import os# 创建文件夹
print('请确保输出的是 1 或者是 2 ,否则会报错')
out_name = input('请输入数字1或者2: 1、清新美女 2、清纯少女 ')
url1 = 'https://www.vmgirls.com/fresh/'
url2 = 'https://www.vmgirls.com/pure/'
if int(out_name) == 1:
url = url2
elif int(out_name)== 2:
url = url1
# 获取响应函数
def send_request(address):
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/95.0.4638.69 Safari/537.36'
}
response = requests.get(url=address, headers=headers)
response.encoding = 'utf-8'
return response# 不知道为啥要这么做,如果不做这步,后面会出错
def save_img(si1, si2, si3, si4): # si1 = 图片名称 si2 = 图片数量 si3 = 图片存储地址 si4 = resp 响应
with open((si3 + '//' + si1), mode='wb') as f:
print('共「' + (str(si2)) + '」张图片' + '正在保存图片:' + si1 + ' 到:「' + si3 + '」文件夹里')# + '剩余' + str(get_img_num - 1),这里不会写,就注释了
f.write(si4.content)
resp_1 = send_request(url)
tree_1 = etree.HTML(resp_1.text)
get_page_num = tree_1.xpath('/html/body/main/div/nav/div/a/text()')[-1]# 精准获取所有页面地址
collout = []# 用来存储所有的页面url
for s1 in range(1, int(get_page_num) + 1):# 第一次循环:拼接url。主要是从第二页开始,url需要在后面加 代码
if s1 == 1:# 因为页面的不同,在第一页的时候,不需要在后面加编号
get_long_url = url
else:
get_long_url = url + f'page/{s1}/'# 将长链接与短链接拼接在一起
collout.append(get_long_url)# 将获取到的全部页数,添加到数组里,方便后面循环
for s2 in collout:# 第二次循环:获取每页每个图片的地址。通过所有的页面,for循环来获取每个页面,每个图片的链接
resp_2 = send_request(s2)# 获取每个页面的响应
tree_2 = etree.HTML(resp_2.text)
get_one_url = tree_2.xpath('/html/body/main/div/div//div/div/a/@href')# 精准获取每一页,每个图片的链接
# 这个s3 这个for 循环需要写在 s2 里面,因为s2 代表的是所有页面,然后每个页面里有24个图片,这时候for循环就会分别获取这24个图片地址
# 全部获取之后在跳出此循环,进入到s4循环里
for s3 in get_one_url:# 第三次循环:获取每个页面的图片地址。
time.sleep(1)
resp_3 = send_request(s3)
tree_3 = etree.HTML(resp_3.text)
get_img_url = tree_3.xpath('/html/body/main/div/div/div/div/div/div/div/a/img/@src')# 精准获取页面里所有图片地址
get_img_num = (len(get_img_url))# 获取每个页面有多少张图片,通过len来获取列表数量
get_img_name_folder = tree_3.xpath('/html/body/main/div/div/div/div/div/h1/text()')# 精准获取该页面的名称,方便后面创建文件夹
# 创建目录
img_path = 'e://img//' + get_img_name_folder# 用于存储文件放入之后的位置,修改'e://img//',可以选择保存后的位置
if not os.path.exists(img_path):# 如果没有这个文件,创建文件夹
os.makedirs(img_path)
print(get_img_name_folder + ' 目录创建成功,准备开始保存图片')
#第四次循环:保存图片。
for s4 in get_img_url:# 通过获取的每一个图片url,进行for循环,这个循环是需要放在s3里的,因为s3是一个列表,包括了该页面所有的图片
time.sleep(1)
resp_4 = send_request(s4)
get_img_name = s4.split('/')[-1] # 通过切割url地址,来获取保存的图片名字,用于输出后的图片名字
# 保存文件
save_img(get_img_name, get_img_num, img_path, resp_4)
send_request(s4)# 关闭每个页面获取到的图片url响应
print('❤ '+get_img_name_folder + ' 图片爬取完毕,准备爬取下一个.......')
send_request(s3)# 关闭每个图片页面的响应
send_request(s2)# 关闭获取所有页面url的响应
send_request(url)# 关闭获取所有页面url的响应
本帖最后由 话痨司机啊 于 2022-5-9 20:58 编辑
from collections import namedtuple
from concurrent.futures import ThreadPoolExecutor
from typing import Dict, List
import re
import requests
import os
from datetime import datetime
import keyboard
from fake_useragent import UserAgent
from lxml import etree
from rich.console import Console
console = Console()
headers = {'User-Agent':UserAgent().random}
DATA = namedtuple('DATA',['year','month','day','title','href'])
url = 'https://www.vmgirls.com/archives.html'
img_list = ['jpg','png','gif','jpeg']
def start_requests():
res = requests.get(url,headers=headers)
et = etree.HTML(res.text)
# 获取全部年份
y = et.xpath('//div[@id="archives"]/h4/text()')
for year in range(1,len(y)+1):
# 每个月
m = et.xpath(f'//div[@id="archives"]//ul[{year}]/li/span/text()')
for month in range(1,len(m)+1):
# 每天
d = et.xpath(f'//div[@id="archives"]//ul[{year}]/li[{month}]/ul/li')
for day in range(1,len(d)+1):
# 每天的网址
_day = et.xpath(f'//div[@id="archives"]//ul[{year}]/li[{month}]/ul/li[{day}]/text()')
_href = et.xpath(f'//div[@id="archives"]//ul[{year}]/li[{month}]/ul/li[{day}]/a/@href')
_title = et.xpath(f'//div[@id="archives"]//ul[{year}]/li[{month}]/ul/li[{day}]/a/text()')
yield DATA(y,m,_day,_title,_href)
def get_data(yield_func):
'''
转换数据
'''
yield from yield_func
def save_img(url,path,title):
'''
保存图片
'''
imgcs = requests.get(url,headers=headers)
et = etree.HTML(imgcs.text)
IMG = et.xpath('//div[@class="nc-light-gallery"]//@href')
for i in range(0,len(IMG)):
if IMG.split('.')[-1] in img_list:
res = requests.get(IMG,headers=headers)
with open(f'{path}/{title}_{i}.jpg','wb') as f:
f.write(res.content)
nowdate = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
console.print(f'创建时间:{nowdate}\n保存路径:{path}\n文件:{title}_{i}.jpg 保存成功!\n提示:按esc退出')
console.print('-'*70)
if keyboard.read_key() == 'esc':
raise KeyboardInterrupt
def mkdir_path(path):
'''
创建路径
'''
path = re.sub(r'[\s]','',path)
if not os.path.exists(path):
os.makedirs(path)
return path
def main():
'''
多线程主函数
'''
with ThreadPoolExecutor(max_workers=5) as executor:
try:
for data in get_data(start_requests()):
path = mkdir_path(os.path.join(os.getcwd(),'美女壁纸',data.year,data.month,data.day[:-2]))
img_name = data.title
url = data.href
executor.submit(save_img,url,path,img_name)
except Exception as e:
console.print('程序即将退出!')
os._exit(0)
if __name__ == '__main__':
main()
也是这个网站,写个多线程的给你参考,我爬了一点,小姐姐不太高清 return response# 不知道为啥要这么做,如果不做这步,后面会出错
---这是返回值,必须有的,给后面的爬取提供页面。
---request.get().text,把text加入进来,完全可以。
爬取,Bs4、正则,得搞定。Bs4,好用;但正则是王道。
哈,加油,起点很高。很赞! 谢谢分享,虽然不懂 感觉跟我刚学爬虫写的差不多 真不错 十分钟爬了一百张 还有很大 的优化空间 爬取规则最好直接正则来写,这样写稍微网站一改就不行了 sifan785622020 发表于 2022-5-8 20:23
感觉跟我刚学爬虫写的差不多
哈哈,我就是刚学的爬虫 10072 发表于 2022-5-8 20:23
真不错 十分钟爬了一百张
坚持下去,一定能爬完的:lol yzxqhdx 发表于 2022-5-8 20:58
还有很大 的优化空间
大佬能给点建议吗{:1_918:} layuai 发表于 2022-5-8 21:24
爬取规则最好直接正则来写,这样写稍微网站一改就不行了
原来如此,感谢大佬指点