可爱女生图片到期了,怎么办?当前是把Python爬虫升级到可爱头像站
Posted 梦想橡皮擦
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了可爱女生图片到期了,怎么办?当前是把Python爬虫升级到可爱头像站相关的知识,希望对你有一定的参考价值。
最近收到 C 友反馈,说 《对 Python 爬虫编写者充满诱惑的网站,《可爱图片》》 这篇博客的目标图片站,已经不能使用了,橡皮擦查阅之后,发现是对方的图片源出了问题,可跟咱一点点关系都没有。
🍀 但是对我们专栏的订阅者可以有影响的,毕竟我们要学习的知识缺少了这么一块,有点不完美了。🍀
正因如此,我们做一下本案例的升级,(如果你在订阅之后,发现其它站点出现类似情况,一定第一时间联系橡皮擦,每个爬虫都质保 5 年)
版权声明:本案例涉及所有内容仅供学习使用,请勿用于商业目的,如有侵权,请及时联系。
学习注意事项:
- 文章会自动省略 http 和 https 协议,学习时请自行在地址中进行补充。
- 目标站点域名为
imeitou
,在下文统一用橡皮擦
代替,学习时请自行拼接。
文章目录
⛳️ 女生头像图片
本次目标站点时【美头】,一个小众站点,是一个专注如提供高清好看头像的小站。
经过简单测试,目标站点翻页规则如下所示。
www.橡皮擦.com/nvsheng/index.html
www.橡皮擦.com/nvsheng/index_2.html
www.橡皮擦.com/nvsheng/index_10.html
注意不要直接访问地址,看前文说明,【橡皮擦】属于密文。
在原案例中,我们使用了三个 Python 模块,分别是 requests
,re
,threading
,其中提及了线程并行模块 threading
,这也是本篇博客的重点内容。
学习的时候你可以两篇博客对比学习,所以橡皮擦在本文中增加一些补充逻辑进入。
本次的目标站点翻页规则属于 URL 数字跳转,难度系数比较低,很容易发现规律,并且点击详细地址链接,得到的详情页面数据无需翻页,所以代码编写逻辑也变简单,整理需求如下所示。
需求整理
- 目标站点的数据量大小是: 1790 页 28628 条数据,比较大,所以学习的时候,我们仅采集前 10 页,此时可以固定最大页,起始页在前文已经固定。
- 原博客中用到了多线程采集详情地址,这里保留该逻辑。
- 下载图片也是采用多线程处理,依旧保留逻辑。
下面进入到编码环节。
⛳️ 实战场景
获取详情页地址
编码的第一个环节,就是将详情页地址采集到一个全局变量中,这里会用到互斥锁,也是使用多线程模块访问全局变量的必备知识点。
在编码环节,重要步骤会在注释中添加,请仔细阅读。
import requests
import re
import threading
import time
headers =
"User-Agent": "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.93 Safari/537.36"
# 详情页图片地址 URL
detail_urls = []
mutex = threading.Lock()
# 循环获取URL
def get_detail_urls(url):
res = requests.get(url=url, headers=headers)
res.encoding = 'gb2312'
if res is not None:
html = res.text # 读取页面源码
# 对目标源码页数据进行裁剪
# 获取 ul class = "g-gxlist-imgbox" 的数据
# 该数据在标签 <ul class="g-gxlist-imgbox"> 和 <div class="pagelist"> 之间
html = html[html.find('<ul class="g-gxlist-imgbox">'):html.find('<div class="pagelist">')]
# 裁剪之后的数据,可以使用正则提取
# 设置正则表达式对象
pattern = re.compile('<a href="(.*?)" target="_blank" title=".*?">')
# 提取详情页地址
find_urls = pattern.findall(html)
if find_urls:
# 上锁
mutex.acquire()
# 添加到全局变量中
detail_urls.extend(find_urls)
# 释放锁
mutex.release()
if __name__ == '__main__':
# 生成分页地址
origin_url = ['http://www.imeitou.com/nvsheng/']
for i in range(2, 11):
origin_url.append(f'http://www.imeitou.com/nvsheng/index_i.html')
# 获取图片详情页地址
for d_url in origin_url:
get_detail_urls(d_url)
# 测试得到的详情页地址列表
# 测试得到 160 条地址,数据量是正确的
print(len(detail_urls))
通过运行上述代码,你已经将地址提取到了全量变量 detail_urls
中,注意在使用的时候进行锁设置,这里的锁是为了后续获取图片地址做的准备。
图片下载线程
import requests
import re
import threading
import time
headers =
"User-Agent": "Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.93 Safari/537.36"
# 详情页图片地址 URL
detail_urls = []
mutex = threading.Lock()
# 循环获取URL
def get_detail_urls(url):
res = requests.get(url=url, headers=headers)
res.encoding = 'gb2312'
if res is not None:
html = res.text # 读取页面源码
# 对目标源码页数据进行裁剪
# 获取 ul class = "g-gxlist-imgbox" 的数据
# 该数据在标签 <ul class="g-gxlist-imgbox"> 和 <div class="pagelist"> 之间
html = html[html.find('<ul class="g-gxlist-imgbox">'):html.find('<div class="pagelist">')]
# 裁剪之后的数据,可以使用正则提取
# 设置正则表达式对象
pattern = re.compile('<a href="(.*?)" target="_blank" title=".*?">')
# 提取详情页地址
find_urls = pattern.findall(html)
if find_urls:
# 上锁
mutex.acquire()
# 添加到全局变量中
detail_urls.extend(find_urls)
# 释放锁
mutex.release()
# 保存图片线程
def save_image():
global detail_urls
while True:
# 上锁
mutex.acquire()
if len(detail_urls) > 0:
# 获取列表第1项
img_url = detail_urls[0]
# 删除列表第1项
del detail_urls[0]
# 释放锁
mutex.release()
res = requests.get(url=img_url, headers=headers)
if res is not None:
html = res.text
# 裁切目标源码,便于后续整体提取
html = html[html.find('<div class="img-list3">'):html.find('<div class="m_ssxx">')]
pattern = re.compile('<img alt=".*?" src="(.*?)" />')
img_list = pattern.findall(html)
if img_list:
for img in img_list:
print(f"线程threading.currentThread().name", "抓取图片中:", img)
try:
res = requests.get(img)
with open(f"images/time.time().png", "wb+") as f:
f.write(res.content)
except Exception as e:
print(e)
else:
print("等待中,长时间等待,可以直接关闭")
if __name__ == '__main__':
# 生成分页地址
origin_url = ['http://www.imeitou.com/nvsheng/']
for i in range(2, 11):
origin_url.append(f'http://www.imeitou.com/nvsheng/index_i.html')
# 获取图片详情页地址
for d_url in origin_url:
get_detail_urls(d_url)
# 测试得到的详情页地址列表
# 测试得到 160 条地址,数据量是正确的
print(len(detail_urls))
# 保存图片线程配置+启动
# 这里我们开启2个线程
save1 = threading.Thread(target=save_image)
save1.start()
# save2 = threading.Thread(target=save_image)
# save2.start()
上述仅使用了 2 个线程,实战中根据电脑配置提高即可。代码运行效果如下所示。
注意提前在项目根目录建立 images
文件夹,然后你就能得到大量头像图片了。
📢📢📢📢📢📢
💗 你正在阅读 【梦想橡皮擦】 的博客
👍 阅读完毕,可以点点小手赞一下
🌻 发现错误,直接评论区中指正吧
📆 橡皮擦的第 786 篇原创博客
从订购之日起,案例 5 年内保证更新
以上是关于可爱女生图片到期了,怎么办?当前是把Python爬虫升级到可爱头像站的主要内容,如果未能解决你的问题,请参考以下文章