目录
前言
一、多线程是什么?
二、首页壁纸爬的步骤
1.主程序(选择爬取功能)
2.三个功能类别(功能类似,内容发生一点点改变)
3.实现具体的抓取功能---(抓取缩略图的网址以此获取后继的高清图片网址)
4.解析获取到的缩略图网址,得到每一个高清图片的数据
5.在本地创建文件夹目录(可以进行路径修改)
6.保存数据
7.关于线程函数的代码说明
三、实现效果
总结
对于爬取图片,当我们想要爬取的数据量非常大时,我们所需要消耗的时间也将非常大。在此,利用python的多线程技术以提高爬取速率。
简单来说,若有多个任务则可以同时执行。如,使用电子设备在学生宿舍使用WIFI上网,学生宿舍里的WIFI可以让所有连上对应WIFI的设备上网
wallhaven网址
def main():
print("======请选择爬取操作功能选项======")
print("A:单页爬取")
print("B:前n页爬取")
print("C:n-m页爬取")
print("D:退出主程序")
print()
while True:
select=input("请输入要操作的选项:")
if select in ("A","a") :
single_page_sipder()
elif select in ("B","b"):
previous_page_sipder()
elif select in ("C","c"):
n_m_page_sipder()
elif select in ("D","d"):
print("2秒后自动退出,欢迎下次再来!!!")
time.sleep(2)
break
else:
print("输入有误,请重新输入!")
if __name__=="__main__":
main()
# 单页爬取
def single_page_sipder():
page = int(input("请输入你要抓取的单页页码:"))
url1 = input("输入wallhaven网址")
img_url = get_img_url(page,url1)
thread_main(img_url)
# 前n页爬取
def previous_page_sipder():
pagen = int(input("请输入你要抓取的前n页页码:"))
url1 = input("输入wallhaven网址")
img_url = get_img_urln(pagen,url1)
thread_main(img_url)
# n-m页爬取
def n_m_page_sipder():
pagen,pagem = list(map(int,input("请输入你要抓取的页数范围:(格式:n-m)").split("-")))
url1 = input("输入wallhaven网址")
img_url = get_img_urlnm(pagen,pagem,url1)
thread_main(img_url)
# 单页抓取
def get_img_url(page,url1):
# wallhaven网址
headers_ = {
"user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.5112.102 Safari/537.36 Edg/104.0.1293.70"
}
url = url1 + f"page={page}"
print(url)
response = requests.get(url=url, headers=headers_)
str_data = response.content.decode("utf-8")
html_obj = etree.HTML(str_data)
img_url = html_obj.xpath("//*[@id='thumbs']/section/ul/li/figure/a[2]/@href")
img_url=[img_url]
print(f"第{page}页缩略图网址抓取成功!!!")
return img_url
# n-m页抓取
def get_img_urlnm(pagen,pagem,url1):
# wallhaven网址
headers_ = {
"user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.5112.102 Safari/537.36 Edg/104.0.1293.70"
}
img_url = []
for i in range(pagen, pagem + 1):
url = url1 + f"page={i}"
print(url)
response = requests.get(url=url, headers=headers_)
str_data = response.content.decode("utf-8")
html_obj = etree.HTML(str_data)
img_url_list = html_obj.xpath("//*[@id='thumbs']/section/ul/li/figure/a[2]/@href")
img_url.append(img_url_list)
print(f"第{i}页缩略图网址抓取成功!!!")
return img_url
# 前n页抓取
def get_img_urln(pagen,url1):
headers_ = {
"user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.5112.102 Safari/537.36 Edg/104.0.1293.70"
}
img_url=[]
for i in range(1,pagen+1):
url=url1+f"page={i}"
print(url)
response=requests.get(url=url,headers=headers_)
str_data=response.content.decode("utf-8")
html_obj=etree.HTML(str_data)
img_url_list=html_obj.xpath("//*[@id='thumbs']/section/ul/li/figure/a[2]/@href")
img_url.append(img_url_list)
print(f"第{i}页缩略图网址抓取成功!!!")
return img_url
# 生成图片数据以及名字-------图片后缀判别更正,图片命名,图片二进制数据生成
def getImg_data(img_url):
headers_ = {
"user-agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/104.0.5112.102 Safari/537.36 Edg/104.0.1293.70"
}
# 获取最后一个斜杠后面的字符串
x = img_url.split('/')[-1]
a = x[0] + x[1] # 获取字符串的前两位
img_url_new = 'https://w.wallhaven.cc/full/' + a + '/wallhaven-' + x + '.jpg' # 拼接字符串,先默认jpg结尾
code = requests.get(url=img_url_new, headers=headers_).status_code
if code == 404: # 若网页返回值为404,则为png结尾
img_url_new = 'https://w.wallhaven.cc/full/' + a + '/wallhaven-' + x + '.png'
img_data = requests.get(url=img_url_new, headers=headers_).content # 获取壁纸图片的二进制数据,加入timeout限制请求时间
img_name = x+img_url_new.split('-')[-1]
return img_data,img_name
# 创建文件夹---返回文件夹目录
def create_file():
keyword = "嘿!看过来!"
if not os.path.exists('E:/wallpapers1'): # 在E盘目录下创建一个名为wallpapers的文件夹
os.mkdir('E:/wallpapers1')
path = 'E:/wallpapers1/' + keyword
if not os.path.exists(path): # 在wallpapers文件夹下创建一个以关键词命名的子文件夹以存放此次下载的所有壁纸
os.mkdir(path)
return path
# 保存图片至路径
def img_save(path,data):
with open(path, 'wb') as fp: # ('w':写入,'b':二进制格式)
fp.write(data)
img_name=path.split("/")[-1]
print(img_name, '下载成功') # 每张图片下载成功后提示
# 需要实现多线程的函数方法
def thread_spider(img_url,i,j):
print(img_url,f"第{i*24+j+1}张")
img_data, img_name = getImg_data(img_url)
path = create_file()
img_path = path + '/' + img_name # 生成图片存储路径
img_save(img_path, img_data) #将图片数据保存至路径img_path下
# 线程主函数
def thread_main(img_url):
img_url_list = [sec for fis in img_url for sec in fis]
print(f'共爬{len(img_url_list)}张壁纸')
# 多线程的创建以及线程的存储
threads = [] # 线程总列表
start=datetime.datetime.now()
# 创建线程
for i in range(0, len(img_url)):
one_page_threads = [] # 某一页内的壁纸网址的线程列表
for j in range(0, len(img_url[i])):
thread=threading.Thread(target=thread_spider,args=(img_url[i][j],i,j,))
one_page_threads.append(thread)
threads.append(one_page_threads)
# 启动线程
for i in range(0, len(img_url)):
for j in range(0, len(img_url[i])):
threads[i][j].start()
time.sleep(1)
# 等待线程执行完毕
for i in range(0, len(img_url)):
for j in range(0, len(img_url[i])):
threads[i][j].join()
end=datetime.datetime.now()
print(end-start)
以上仅仅是个人的开发过程的分享,如有不足,请大佬们多指教