近日因为一直闲着没事情做,所以笔者决定写一个爬虫来爬取一下某个固定网站的图片,仅供娱乐。
题外话:
该程序主要实现如何根据用户输入的搜索字段和下载数量来下载相应的图片集合,然后将其转化为exe可执行文件。
另外,本文适合刚刚接触Python或者刚刚开始接触爬虫的人阅读,因为用的都是比较初级的知识,所以没有使用代理,也没有使用多线程,代码也只有70多行。
大家需要注意,网站可能随时会更新,用这种方法制作出来的爬虫在网页结构变化后就无法使用。
最后笔者将代码与结果已经上传到Github,感兴趣的伙伴可以star一下。
https://github.com/kiva12138/ReptileForPictures
笔者的QQ是1574143668,有问题的小伙伴随时来交流。
正式实现:
首先我们需要决定爬取的网站,笔者找来找去发现一个网站的内容相对固定,而且更新不频繁,那就是美图录网站。而且这个网站有个搜索特点,那就是每次搜索结果只有前20条,感觉像一个新手制作的网站,而这不是刚刚好适合我们爬取吗?
其次我们需要明白这个网站搜索结果的组织结构,该组织结构为:
搜索结果页面(最多20条目)-> 每个图集的详细内容(每页最多4张图片,页数不确定)
剩下的废话不多说,直接贴上代码,在代码中解释。
# 引入我们所需要的包
import requests
from lxml import etree
import time
import os
# 定义一个写入图片的函数。
# 第一个参数是图片内容,第二个是该图片名称,第三个参数是文件夹名称
# 剩下的都是一些基础的Python IO基础了
def writeToFile(content, number, context_name):
with open(str(context_name) + '\\' + str(number) + '.jpg', 'wb') as f:
try:
f.write(content)
except:
print('淦!鬼知道为什么文件写入失败!可能搜的东西有问题或者网站改了。')
if __name__ == '__main__':
input_content = '' # 需要搜索的内容
want_mount = 1 # 默认的想要下载的图片集合数量
current_mount = 0 # 搜索到的图片集合的数量
sleep_time = 1 # 每次下载间隔的时间,防止访问过于频繁而被ban
exit_code = 'iwantquit' # 输入该字段就会退出程序
search_url = 'https://www.meitulu.com/search/' # 搜索前缀
site_prefix = 'https://www.meitulu.com' # 网址前缀
# 请求头
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 6.2; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/27.0.1453.94 '
'Safari/537.36 '
}
print('为了保证你的访问正常,我们设置下载间隔时间位1秒,可能有点小慢,但是足够你欣赏美图。')
# 定义一个死循环,只有输入Ctrl C或者输入“iwantquit”的时候退出
while True:
print('----------------------------------------------------')
input_content = input('请输入要搜索的内容(输入iwantquit退出程序):')
if input_content == exit_code:
break
# 获取搜索结果页面 并进行编码处理 同时获取选择器
search_html = requests.get(search_url + str(input_content))
search_html.encoding = 'utf-8'
search_selector = etree.HTML(search_html.text)
# 该处的Xpath可以使用浏览器的选择功能找到
dataList = search_selector.xpath('/html/body/div[2]/div[2]/ul/li')
# 如果没有找到任何图集,那么直接要用户再次输入
current_mount = len(dataList)
if current_mount == 0:
print('该搜索字段没有找到任何美图。')
continue
print('一共找到了' + str(current_mount) + '个美图集。(好像最多就是20)')
# 限制用户的下载数量
want_mount = int(input('请输入你想下载的图集数量(<' + str(current_mount) + '):'))
if want_mount > current_mount:
print('贪得无厌不可取,只给你下载' + str(current_mount) + '张')
want_mount = current_mount
# 开始下载
for i in range(1, want_mount + 1):
# 获取标题 作为文件夹的名称
title = dataList[i].xpath('p[2]/a/text()')[0]
# 创建新的文件夹
if not os.path.isdir(title):
os.mkdir(title)
print('准备下载图集:' + title)
content_url = dataList[i].xpath('a/@href')[0]
last_page_url = '' # 记录上一页的url
current_page_url = content_url # 记录当前页的url
number = 0 # 用来对单张图片进行命名
page = 1 # 记录页数
# 这个循环用来不断获取"下一页"
# 直到当前页的url和上一页的url不再变化的时候就可以退出循环了
while current_page_url != last_page_url:
print('正在下载第' + str(page) + '页的图片...')
time.sleep(sleep_time) # 等待一段时间
# 获取该page的页面 并进行编码处理 同时获取选择器
content_html = requests.get(current_page_url)
content_html.encoding = 'utf-8'
content_selector = etree.HTML(content_html.text)
# 获取图片资源 并且写入文件
content_dataList = content_selector.xpath('/html/body/div[4]/center/img')
for img_data in content_dataList:
img_src = img_data.xpath('@src')[0]
img = requests.get(img_src)
writeToFile(img.content, number, title)
number += 1
# 更新当前页 与下一页
last_page_url = current_page_url
current_page_url = site_prefix + content_selector.xpath('/html/body/center/div/a')[-1].xpath('@href')[0]
page += 1
最后一步:
在将程序调试到没有错误后,最后我们要实现的是如何将Python文件转化为exe文件。最简单的方式就是采用pyinstalller来将py文件转化为exe文件。
首先如果没有pyinstaller的话需要安装:
pip install pyinstaller
然后在py目录下执行命令将其转化为exe文件:
pyinstaller -F -i .\timg.ico .\test.py
其中-i与其参数指定的是文件的图表,可选项。