Python爬虫1------(爬取图片实现多页面下载)

1.爬取任务

        获取必应壁纸 - Bing首页每日壁纸下载 (peapix.com)中的图片,且实现多个页面的爬取并进行下载至相对应的文件夹,实现多线程以及进度条加快和显示爬虫进度,将获取的图片路径以及标题存入csv文件中。

2.使用技术

        爬取图片过程中使用的是BeautifulSoup进行解析html文本获取所需要的,使用了ThreadPoolExecutor进行多线程加速,使用tqdm实现下载进度显示,使用csv进行写入csv文件操作。

3.需要安装第三方库

import csv
import os
import requests
from bs4 import BeautifulSoup
import time
from tqdm import tqdm
from concurrent.futures import ThreadPoolExecutor

4.源码

import csv
import os
import requests
from bs4 import BeautifulSoup
import time
from tqdm import tqdm
from concurrent.futures import ThreadPoolExecutor


# 获取图片地址并且写入csv中
def getUrlsAndWriteInCsv(list):
    # 设置下载的目录 不存在则创建
    csvDirectory = "csvfiles\\bing"
    if not os.path.exists(csvDirectory):
        os.makedirs(csvDirectory)
    # 设置csv文件 将信息写入文件
    csvFilePath = os.path.join(csvDirectory, str(i)) + ".csv"
    print(csvFilePath)
    with open(csvFilePath, 'w', encoding='utf-8', newline="") as f:
        # 2. 基于文件对象构建 csv写入对象
        csv_writer = csv.writer(f)
        # 3. 构建列表头
        csv_writer.writerow(["图片名称", "图片路径"])
        for k in tqdm(list, desc='图片下载'):
            url1 = "https://peapix.com" + k.attrs['href']
            response1 = requests.get(url1, headers=headers)
            if response1.status_code == 200:
                response1 = response1.text
                soup1 = BeautifulSoup(response1, 'lxml')
                pictureSrc = soup1.find('a', "btn btn-secondary w-100").attrs['href']
                pictureTitle = k.attrs['title']
                # 写入csv文件内容
                csv_writer.writerow([pictureTitle, pictureSrc])
                directory = 'images//bing//' + str(i)
                if not os.path.exists(directory):
                    os.makedirs(directory)
                    print(f"{directory}目录创建成功")
                # 定义下载一张图片的开始时间
                startTime = time.time()
                  # downloadPictures(directory, pictureTitle, pictureSrc)
                endTime = time.time()
                # 若五秒未下载完成图片则自动跳过
                if (endTime - startTime) > 5:
                    print(f"{pictureTitle} 图片下载超过五秒\n")
                    continue
                print(pictureTitle, '下载成功!!!\n')


# 下载图片
def downloadPictures(directory, pictureTitle, pictureSrc):
    # 设置图片下载存储的路径 添加图片后缀名
    img_path = directory + "//" + pictureTitle + '.jpg'
    # 此处为图片内容的二进制
    img_data = requests.get(url=pictureSrc, headers=headers).content
    with open(img_path, 'wb') as f:
        f.write(img_data)


def main(url, headers, params):
    params['page'] = i
    response = requests.get(url, headers=headers, params=params)
    if response.status_code == 200:
        response = response.text
        soup1 = BeautifulSoup(response, 'lxml')
        picturesList = soup.find_all('a', class_="image-list__link")
        getUrlsAndWriteInCsv(picturesList)


# 微软图片的获取 contents获取子节点里面的数据 string和text都可直接获取数据
# 先进行图片加载,再进行图片下载
if __name__ == '__main__':
    mainStartTime = time.time()
    url = "https://peapix.com/bing/cn"
    headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36 Edg/114.0.1823.58'}
    params = {
        'page': 1
    }
    picturesList = []  # 获取的图片标签
    pictureDict = {}  # 前者为图片名称,后者为相对地址
    # 创建一个有50个线程的线程池 max_workers = 12
    with ThreadPoolExecutor(max_workers=8) as t:
        for i in tqdm(range(1, 3), desc="所有页面加载"):
            t.submit(main(url, headers, params), name=f"线程{i}")  # f是format  格式化字符串
    print("所有图片下载成功")
    mainEndTime = time.time()
    print(f"爬取{url}页面图片总耗时{mainEndTime - mainStartTime}s")

5.实验总结

        使用BeautifulSoup更加清晰简单的进行定位,获取我们所需要的信息,并将信息写入文件,当然,由于每一张图片需要向一个新的页面发送请求,以至于效率有点慢,所有采取了线程池来加快图片下载速率,总的来说,还是不错的,值得学习,欢迎小伙伴交流以及探讨,记得点个关注和赞哦!!!

猜你喜欢

转载自blog.csdn.net/m0_64238843/article/details/131491719