python学习笔记5-利用多线程爬取一系列网页的相关图片

python学习笔记4-爬取一系列网页的相关图片 中,我用 requests+BS4 爬取了一个系列网页的图片。

但是,效率太低。

究其原因是,图片是一张一张下载的,一张下载完毕后,才能下载下一张。能不能同时下载多张呢?

答案是肯定的,利用 python 中的线程就可以做到同时下载多张图片,提高下载效率。

首先,导入相关的模块,其中的 threading 就是 python 线程模块。

# -*- coding:utf-8 -*-

import os
import requests   # requests 模块
from bs4 import BeautifulSoup  # 解析 HTML 的模块 导入 BS ,版本 4。
import lxml   # bs4的解析插件模块
import time
import threading

定义一些可能用到的变量

# 定义 第一个页面的网址和该系列页面的根目录,防止图片用的是相对路径
weburl = r"https://www.xx.com/2019/1211/47543.html"
webroot = r"https://www.xx.com/2019/1211/"

# 翻页的, 当前页面class。具体分析见上一篇文章。
pageRe = "thisclass"

# 设置文件夹路径
localURL = r"images/"

# 设置页面路径 list
pagesList = [weburl]  # 默认第一个页面

# 设置图片路径 list,所有的图片都要放在这个 list 里。
srcList = []

# 设置请求 headers,伪装浏览器 并接受中文数据
headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/79.0.3945.79 Safari/537.36',
    'Accept-Language': 'zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2',
    'Connection': 'keep-alive'
}

定义几个要用到的函数

# 获取指定页面的HTML
def getHTML(weburl):
    webreq = requests.get(weburl,headers=headers)
    webreq.encoding = webreq.apparent_encoding  # 防止中文乱码
    return webreq.text

# 解析指定页面的HTML,获取图片路径 list
def getWebImgSRC(bs,pageurl):
    global srcList
    #  用 BeautifulSoup 获取页面中指定位置的图片
    imgs = bs.select(".content img")
    for item in imgs:
        srcList.append( item.get("src") ) # 获取每张图片的路径,存入srcList 中
    print(pageurl+" 图片数组获取完成")

# 递归调用,获取网页 list
def getWebList(pageurl):
    global pagesList
    print("开始获取"+pageurl+"的信息")
    webreq = requests.get( pageurl ,headers=headers ) #  从第一个页面开始分析翻页
    webreq.encoding = webreq.apparent_encoding  # 防止中文乱码
    html = webreq.text
    bs = BeautifulSoup(html,"lxml")
    getWebImgSRC(bs, pageurl)  # 解析页面获取 图片路径到 srcList 里
    # 利用 BeautifulSoup 获取翻页的 li。
    pagesLi = bs.select(".dede_pages li")
    for index in range(len(pagesLi)):  # 因为要获取当前页的索引,所以就利用索引遍历翻页li标签
        if pageRe in str(pagesLi[index].get("class")):
            if index + 1 >= len(pagesLi):
                print("页面已经翻完啦~")
                return False
            # 获取下一个页面的地址
            nextPage = str(pagesLi[index + 1].find("a").get("href"))
            pagesList.append(webroot+nextPage)
            break
    getWebList(webroot+nextPage)  # 开始递归调用

开始执行代码:主要思想就是,让每个图片都用一个线程去下载,就相当于多了很多帮手,帮我们下载,可以大大提高页面的下载效率。

# 开始执行代码
start = time.time()

getWebList(pagesList[0])  # 从第一个页面开始爬取各个页面路径

print( "图片下载开始:" )

downloadThreads = []  # 下载线程 的 list
for item in srcList:  # 多线程依次下载图片
    # 创建一个线程对象
    downloadThread = threading.Thread(target=downImage, args=(item,) )
    downloadThreads.append(downloadThread)
    downloadThread.start()  # 启动线程
for item in downloadThreads:
    item.join()

end = time.time()
print("图片下载完毕,所用时间:%s"%(end-start))

完工。

通过时长对比,原来要下载 700多s 的图片,被50s内下载完毕。 这个效率提高的不是一点半点啊~~~ 

绅士们,可以点赞了~

发布了73 篇原创文章 · 获赞 97 · 访问量 4万+

猜你喜欢

转载自blog.csdn.net/weixin_42703239/article/details/103672139
今日推荐