【玩转Python系列【小白必看】Python多线程爬虫:下载表情包网站的图片

news2024/11/16 17:32:27

文章目录

  • 前言
    • 1. 导入模块和库
    • 2. 定义函数 `download_image(url, filepath)`
    • 3. 定义函数 `get_page()`
    • 4. 主程序入口
  • 完整代码
    • 运行效果
  • 结束语

在这里插入图片描述

前言

本文主要介绍了使用Python编写的多线程爬虫程序,用于下载表情包网站上的图片。通过解析网页内容和使用XPath定位,可以获取到图片的URL,并将其保存到本地。

1. 导入模块和库

在这里插入图片描述

import requests
from lxml import etree
from threading import Thread
from queue import Queue
import ssl
ssl._create_default_https_context = ssl._create_unverified_context
  1. import requests:导入requests库,它是一个用于发送HTTP请求的流行库,可以方便地进行网络通信。
  2. from lxml import etree:从lxml库中导入etree模块,它用于处理XML数据,提供了一种灵活且高效的方式来解析和操作XML文档。
  3. from threading import Thread:从threading库中导入Thread类,它用于创建并管理线程,可以实现多任务并发执行。
  4. from queue import Queue:从queue库中导入Queue类,它是Python内置的线程安全的队列,用于在多线程环境下进行安全的数据交换。
  5. import ssl:导入ssl库,它提供了用于操作SSL/TLS协议的函数,用于创建和配置安全套接字。
  6. ssl._create_default_https_context = ssl._create_unverified_context:设置SSL上下文,将验证关闭,以允许使用不受信任的证书。

2. 定义函数 download_image(url, filepath)

在这里插入图片描述

def download_image(url, filepath):
    headers = {'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.70 Safari/537.36'}
    resp = requests.get(url, headers=headers)
    with open(filepath, 'wb') as f:
        f.write(resp.content)
  1. headers定义了一个字典变量,其中包含了User-Agent头信息。User-Agent头部告诉服务器发送请求的客户端程序的类型和版本号。这里使用常见的浏览器User-Agent信息,以模拟浏览器行为。

  2. resp = requests.get(url, headers=headers)发送GET请求到指定的URL,并传入了上面定义的headers。requests.get()返回一个Response对象,该对象包含服务器响应的内容和其他相关信息。

  3. with open(filepath, 'wb') as f:打开指定的文件路径,使用二进制模式写入文件。'wb'表示以二进制写入模式打开文件。

  4. f.write(resp.content)将从服务器响应中获得的原始二进制数据写入文件。resp.content获取响应的内容,其中包含了图像的二进制数据。

3. 定义函数 get_page()

在这里插入图片描述

def get_page():
    while not q.empty():
        url = q.get()
        resp = requests.get(url)
        e = etree.HTML(resp.text)
        src_list = e.xpath('//div[@class="tagbqppdiv"]/a/img/@data-original')
        name_list = e.xpath('//div[@class="tagbqppdiv"]/a/img/@title')
        for src, name in zip(src_list, name_list):
            end = src.split('.')[-1]
            new_name = f'doutu/{name}.{end}'.replace('?', '')
            print(f'正在下载{new_name}')
            download_image(src, new_name)
  1. while not q.empty(): 循环直到队列q为空。
  2. url = q.get() 从队列q中取出一个元素,赋值给变量url
  3. resp = requests.get(url) 发送GET请求到指定的url,并返回Response对象,赋值给变量resp
  4. e = etree.HTML(resp.text) 使用etree.HTML()将获取到的响应文本转换成可进行XPath查询的ElementTree对象,赋值给变量e
  5. src_list = e.xpath('//div[@class="tagbqppdiv"]/a/img/@data-original') 使用XPath定位找到所有<div class="tagbqppdiv"><a><img>标签的data-original属性值,保存在列表src_list中。
  6. name_list = e.xpath('//div[@class="tagbqppdiv"]/a/img/@title') 使用XPath定位找到所有<div class="tagbqppdiv"><a><img>标签的title属性值,保存在列表name_list中。
  7. for src, name in zip(src_list, name_list): 遍历src_listname_list中的元素,依次赋值给变量srcname
  8. end = src.split('.')[-1]src按照.进行分割,取最后一个元素作为文件扩展名,赋值给end变量。
  9. new_name = f'doutu/{name}.{end}'.replace('?', '') 根据获取到的文件名、扩展名以及固定的目录路径,拼接成新的文件路径字符串。并且移除文件名中的问号字符(如果有的话)。
  10. print(f'正在下载{new_name}') 打印提示信息,显示当前正在下载的文件名。
  11. download_image(src, new_name) 调用download_image函数,下载并保存图片。

4. 主程序入口

在这里插入图片描述

if __name__ == "__main__":
    q = Queue()
    for i in range(1, 10):
        q.put(f'https://www.fabiaoqing.com/biaoqing/lists/page/{i}.html')

    for j in range(3):
        t = Thread(target=get_page)
        t.start()
  1. q = Queue() 创建一个队列对象,用于存储要下载的网页URL。
  2. 使用for循环将从1到9的数字作为参数拼接成网页URL,并将URL放入队列q中。
  3. for j in range(3): 使用for循环创建3个线程。
  4. t = Thread(target=get_page) 创建一个线程,目标函数是get_page函数。
  5. t.start() 启动线程,开始执行get_page函数。

完整代码

import requests  # 导入requests库,用于发送HTTP请求
from lxml import etree  # 导入lxml库中的etree模块,用于处理和解析XML数据
from threading import Thread  # 导入threading库中的Thread类,用于创建线程
from queue import Queue  # 导入queue库中的Queue类,用于创建线程安全的队列
import ssl  # 导入ssl库,用于创建和配置安全套接字
ssl._create_default_https_context = ssl._create_unverified_context  # 设置SSL上下文,允许使用不受信任的证书

def download_image(url, filepath):
    headers = {'User-Agent':'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/78.0.3904.70 Safari/537.36'}  # 定义请求头部信息,模拟浏览器访问
    resp = requests.get(url, headers=headers)  # 发送GET请求到指定的URL,并传入请求头部信息
    with open(filepath, 'wb') as f:  # 使用二进制写入模式打开指定文件路径
        f.write(resp.content)  # 将响应内容的二进制数据写入文件

def get_page():
    while not q.empty():  # 当队列q不为空时循环执行以下操作
        url = q.get()  # 从队列q中获取一个元素,赋值给变量url
        resp = requests.get(url)  # 发送GET请求到指定的URL
        e = etree.HTML(resp.text)  # 将响应内容解析为可进行XPath查询的ElementTree对象,赋值给变量e
        src_list = e.xpath('//div[@class="tagbqppdiv"]/a/img/@data-original')  # 使用XPath定位找到所有满足条件的img标签的data-original属性值,返回一个列表
        name_list = e.xpath('//div[@class="tagbqppdiv"]/a/img/@title')  # 使用XPath定位找到所有满足条件的img标签的title属性值,返回一个列表
        for src, name in zip(src_list, name_list):  # 使用zip函数将src_list和name_list中的元素逐个配对
            end = src.split('.')[-1]  # 将src按照'.'进行分割,并取最后一个元素作为文件扩展名,赋值给变量end
            new_name = f'doutu/{name}.{end}'.replace('?', '')  # 根据获取到的文件名、扩展名以及固定的目录路径,拼接成新的文件路径字符串,并移除文件名中的问号字符(如果有的话)
            print(f'正在下载{new_name}')  # 打印提示信息,显示当前正在下载的文件名
            download_image(src, new_name)  # 调用download_image函数,下载并保存图片

if __name__ == "__main__":
    q = Queue()  # 创建一个线程安全的队列对象
    for i in range(1, 10):
        q.put(f'https://www.fabiaoqing.com/biaoqing/lists/page/{i}.html')  # 将拼接好的URL放入队列q中,用于存储要下载的网页URL

    for j in range(3):  # 循环3次
        t = Thread(target=get_page)  # 创建一个线程,目标函数是get_page函数
        t.start()  # 启动线程,开始执行get_page函数

运行效果

在这里插入图片描述

结束语

多线程爬虫是一种高效的爬取网页内容的方式,在对大量图片进行下载时尤为有效。本文提供了一个简单的实例,展示了如何使用Python的requests、lxml和threading库编写多线程爬虫程序。
通过前言和代码实例,读者可以学习到如何导入必要的模块和库、定义下载图片函数、创建线程以及使用队列进行任务分配。
希望本文能够对读者理解和使用多线程爬虫程序提供一些帮助。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/814653.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Spring优雅的在事务提交/回滚前后插入业务逻辑

业务背景 业务那边想要统计下我们这边每天注册商户成功和失败的数量&#xff0c;你看看怎么给他弄下这个功能 功能实现 TransactionSynchronizationManager.registerSynchronization&#xff0c;发现这是spring事务提供的注册回调接口的方法。 在事务注解方法中&#xff0c…

Java 版 spring cloud + spring boot 工程系统管理 工程项目管理系统源码 工程项目各模块及其功能点清单

工程项目各模块及其功能点清单 一、系统管理 1、数据字典&#xff1a;实现对数据字典标签的增删改查操作 2、编码管理&#xff1a;实现对系统编码的增删改查操作 3、用户管理&#xff1a;管理和查看用户角色 4、菜单管理&#xff1a;实现对系统菜单的增删改查操…

python中有哪些比较运算符

目录 python中有哪些比较运算符 使用比较运算符需要注意什么 总结 python中有哪些比较运算符 在Python中&#xff0c;有以下比较运算符可以用于比较两个值之间的关系&#xff1a; 1. 等于 ()&#xff1a;检查两个值是否相等。 x y 2. 不等于 (!)&#xff1a;检查两个…

2024考研408-计算机网络 第一章-计算机网络体系结构学习笔记

文章目录 前言一、计算机网络概述1.1、概念及功能1.1.1、计算机网络的概念1.1.2、计算机网络的功能功能1、数据通信功能2、资源共享功能3、分布式处理功能4、提高可靠性&#xff08;分布式处理引申功能&#xff09;功能5、负载均衡&#xff08;也是分布式处理引申功能&#xff…

23 张图详解路由协议

路由的概念 在 TCP/IP 通信中&#xff0c;网络层的作用是实现终端的点对点通信。IP 协议通过 IP 地址将数据包发送给目的主机&#xff0c;能够让互联网上任何两台主机进行通信。IP 地址可以识别主机和路由器&#xff0c;路由器可以把全世界的网络连接起来。 什么是路由器 路由…

使用Flutter的image_picker插件实现设备的相册的访问和拍照

文章目录 需求描述Flutter插件image_picker的介绍使用步骤1、添加依赖2、导入 例子完整的代码效果 总结 需求描述 在应用开发时&#xff0c;我们有很多场景要使用到更换图片的功能&#xff0c;即将原本的图像替换设置成其他的图像&#xff0c;从设备的相册或相机中选择图片或拍…

【LeetCode 75】第十五题(1456)定长子串中元音的最大数目

目录 题目&#xff1a; 示例&#xff1a; 分析&#xff1a; 代码运行结果&#xff1a; 题目&#xff1a; 示例&#xff1a; 分析&#xff1a; 就难度而言&#xff0c;我觉得算不上中等&#xff0c;因为和上一题基本一致&#xff0c;只不过上一题是求最大平均数&#xff0c…

基于Django美食分享交流网站-计算机毕设 附源码10913

美食分享交流网站 摘 要 大数据时代下&#xff0c;数据呈爆炸式地增长。为了迎合信息化时代的潮流和信息化安全的要求&#xff0c;利用互联网服务于其他行业&#xff0c;促进生产&#xff0c;已经是成为一种势不可挡的趋势。在美食分享的要求下&#xff0c;开发一款整体式结构的…

为什么计算机对浮点型数字计算存在误差

我们输入的十进制小数在计算机中都是以二进制进行存储。比如&#xff1a; 我们把0.25转换为二进制 0.25 * 2 0.5 取0 0.50 * 2 1.0 取1 所以十进制0.25的二进制应当为0.01但是我们把0.3转换为二进制存储 0.3 * 2 0.6 取0 0.6 * 2 1.2 取1 0.2 * 2 0.4 取0 0.4 * …

在腾讯云服务器OpenCLoudOS系统中安装mysql(有图详解)

1. 创建MySQL安装目录 mkdir -p app/soft//mysql 2. 进入MySQL安装目录&#xff0c;下载&#xff0c;安装 cd /app/soft/mysql/ wget http://dev.mysql.com/get/mysql-5.7.26-1.el7.x86_64.rpm-bundle.tar 得到安装包&#xff1a; 解压安装包&#xff1a; 查看系统是否自带…

使用Python机器学习预测外卖送餐时间!

大家好&#xff0c;我是小F&#xff5e; 现在的天气是一天比一天热&#xff0c;好多人周末休息在家的时候&#xff0c;就会选择点外卖&#xff0c;毕竟出去一趟又晒又热。 如果你太饿了&#xff0c;点餐太晚了&#xff0c;就可能去关注外卖员送餐到哪了&#xff0c;还有多少时间…

Kotlin泛型的协变与逆变

以下内容摘自郭霖《第一行代码》第三版 泛型的协变 一个泛型类或者泛型接口中的方法&#xff0c;它的参数列表是接收数据的地方&#xff0c;因此可以称它为in位置&#xff0c;而它的返回值是输出数据的地方&#xff0c;因此可以称它为out位置。 先定义三个类&#xff1a; op…

《golang设计模式》第一部分·创建型模式-03-建造者模式(Builder)

文章目录 1. 概念1.1 角色1.2 类图 2. 代码示例2.1 设计2.2 代码2.3 类图 1. 概念 1.1 角色 Builder&#xff08;抽象建造者&#xff09;&#xff1a;给出一个抽象接口&#xff0c;以规范产品对象的各个组成成分的建造。ConcreteBuilder&#xff08;具体建造者&#xff09;&a…

移动机器人和UGV的自主导航(Matlab代码Simulink)

&#x1f4a5;&#x1f4a5;&#x1f49e;&#x1f49e;欢迎来到本博客❤️❤️&#x1f4a5;&#x1f4a5; &#x1f3c6;博主优势&#xff1a;&#x1f31e;&#x1f31e;&#x1f31e;博客内容尽量做到思维缜密&#xff0c;逻辑清晰&#xff0c;为了方便读者。 ⛳️座右铭&a…

Redis - 底层数据结构

简介 Redis 的底层数据结构主要以下几种&#xff1a; SDS(Simple Dynamic String, 简单动态字符串)ZipList(压缩列表)QuickList(快表)Dict(字典)IntSet(整数集合)ZSkipList(跳跃表) 简单动态字符串 在 Redis 中&#xff0c;并不会直接使用 C 语言自带的字符串结构作为实际的…

hvv 云安全专项检测工具

过去的一年里&#xff0c;我们可能已经注意到了一个明显的趋势&#xff1a;安全对抗正逐步迁移至云端。 如&#xff1a;今年hw的要求中增加了云资产相关的得分项计算 如&#xff1a;越来越多的安全工具开始专注于云安全检测方向 如&#xff1a;越来越多的安全峰会加入了云原…

“一种蒸发冷凝水去除氨氮装置”技术专利

蒸发器中随着母盐液的蒸浓&#xff0c;溶液温度升高&#xff0c;由于氨氮易挥发的特性&#xff0c;游离氨挥发于水蒸气中&#xff0c;从而导致冷凝水中氨氮浓度上升&#xff0c;而影响出水水质。 “一种蒸发冷凝水去除氨氮装置”专利(证书号&#xff1a;第19422309号;专利号&am…

【前端】javascript+html+css 家具销售网站(代码+报告)

&#x1f449;博__主&#x1f448;&#xff1a;米码收割机 &#x1f449;技__能&#x1f448;&#xff1a;C/Python语言 &#x1f449;公众号&#x1f448;&#xff1a;测试开发自动化【获取源码商业合作】 &#x1f449;荣__誉&#x1f448;&#xff1a;阿里云博客专家博主、5…

移动端个人中心UI设计

效果图 源码如下 页面设计 <template><div class"container"><!-- 顶部用户信息 start--><div class"header"><div class"user-info"><van-image class"user-img" round width"70" :sr…

【打造超酷的GitHub主页】

文章目录 Github状态信息-api账户信息统计最常用语言Repo卡片 社交统计统计访问次数徽标 首先上地址&#xff1a;https://gitee.com/java_wxid/giteeprofile/blob/master/README.md 为了照顾一部分网络较差的的朋友们&#xff0c;这里使用国内的gitee仓库将主页代码提供给大家&…