- 作者:20岁爱吃必胜客(坤制作人),近十年开发经验, 跨域学习者,目前于海外某世界知名高校就读计算机相关专业。
- 荣誉:
阿里云博客专家认证
、腾讯开发者社区优质创作者,在CTF省赛校赛多次取得好成绩。跨领域学习
,喜欢摄影、弹吉他、咏春拳。文章深入浅出、语言风趣
;爱吃必胜客社区创立者,旨在“发现美 欣赏美
⭐️前言
Python 多线程(multi-threading)
是一种利用多个线程同时执行任务
的技术,它旨在提高程序的运行效率和性能。
⭐️分析
Python 中多线程的实现主要基于 threading 模块
。在该模块中,我们可以通过创建一个 Thread 对象来启动一个新线程
,并通过 start()
方法来启动该线程的执行
。与此相应的,我们还需要定义一个所谓的“线程函数”
(Thread Function),即我们希望新线程执行的函数
。通常情况下,该函数的形式为:
def thread_func(args): # 线程要执行的操作
其中 args
是线程函数接收的参数,而具体的线程操作就在函数体内实现了。
🌟 其他模块
除了 threading 模块外,Python 还提供了一些相关的库和方法
,如 Queue、Lock 和 RLock等
,可以对多线程编程进行更深入和细节的控制和处理
。
🌟 注意GIL
需要注意
的是,由于 Python 的全局解释器锁(Global Interpreter Lock, GIL)
的存在,使得在使用多线程
时,无法真正实现并行计算
,只能通过线程间的切换来模拟多个线程同时运行
。因此,在考虑使用多线程技术来优化程序性能时,需要详细评估程序结构和运行环境
,以便选择合适的算法和工具进行优化
。
⭐️ 多线程用来做什么
Python 多线程常用于以下几种情况:
网络编程
:Python 中的socket 模块支持多线程
,可以实现多个客户端与服务器的并发通信
。IO 密集型任务
:对于 CPU 耗时相对较短,但需要频繁读写数据的任务,如文件操作、爬虫等
,使用多线程可以提高程序的运行效率。并发控制
:利用多线程可以实现对共享资源的并发访问和管理
,如访问数据库
等。可视化界面
:在 Python 的GUI 编程
中,通过多线程技术
能够让用户界面保持响应
,使得程序更加友好和易用
。
需要注意的是,在选择使用多线程时,需要仔细评估程序结构和运行环境,避免出现线程安全问题和性能瓶颈。
🌟 多线程应用示例
以下是两个常见的 Python 多线程应用示例:
多线程下载文件
该示例演示如何使用 Python 多线程技术下载多个文件,从而加快下载速度。在该示例中,我们使用 threading 模块创建多个线程
,每个线程负责下载一个文件
。
import requests import threading def download(url, filename): # 下载文件 content = requests.get(url).content with open(filename, "wb") as f: f.write(content) if __name__ == '__main__': urls = ["http://example.com/file1", "http://example.com/file2", "http://example.com/file3"] filenames = ["file1.txt", "file2.txt", "file3.txt"] threads = [] for i in range(3): t = threading.Thread(target=download, args=(urls[i], filenames[i])) threads.append(t) # 启动多线程 for t in threads: t.start() # 等待所有线程完成 for t in threads: t.join()
解析 HTML 页面
该示例演示如何使用 Python 多线程技术加快解析 HTML 页面的速度
。在该示例中,我们使用 threading 模块创建多个线程,每个线程负责下载并解析一个页面
,最后将结果合并为一个列表。
import requests import threading from bs4 import BeautifulSoup def parse_page(url): # 下载页面 content = requests.get(url).content soup = BeautifulSoup(content, "html.parser") # 解析页面 results = soup.find_all("div", class_="result") return results if __name__ == '__main__': urls = ["http://example.com/page1", "http://example.com/page2", "http://example.com/page3"] threads = [] for url in urls: t = threading.Thread(target=parse_page, args=(url,)) threads.append(t) # 启动多线程 for t in threads: t.start() # 合并结果 results = [] for t in threads: results += t.join()
需要注意的是,在选择使用多线程时,需要仔细评估程序结构和运行环境
实例爬虫-完整源代码
以下是一个简单的爬虫示例
,使用Python中的requests
和BeautifulSoup库
来获取网页内容并提取其中的信息。这个爬虫程序可以从豆瓣电影Top250页面中提取电影名称、评分、导演和演员等信息
,并将其保存到一个CSV文件
中。
import requests from bs4 import BeautifulSoup import csv # 定义要爬取的页面URL url = 'https://movie.douban.com/top250' # 发送HTTP请求获取页面内容 response = requests.get(url) # 使用BeautifulSoup解析HTML页面 soup = BeautifulSoup(response.text, 'html.parser') # 遍历每个电影条目,并提取电影信息 movies = [] for li in soup.find_all('li', class_='item'): # 获取电影名称 name = li.find('span', class_='title').text # 获取电影评分 rating = li.find('span', class_='rating_num').text # 获取电影导演和演员 info = li.find('div', class_='bd').p.text.strip().split('\n')[0] # 提取导演和演员信息 director = info.split(':')[0] actors = [x.strip() for x in info.split(':')[1].split('/')] # 将电影信息添加到列表中 movies.append([name, rating, director, actors]) # 将电影信息保存到CSV文件中 with open('douban_movies.csv', 'w', newline='', encoding='utf-8') as csvfile: writer = csv.writer(csvfile) writer.writerow(['电影名称', '评分', '导演', '演员']) writer.writerows(movies) print('豆瓣电影Top250信息已保存到douban_movies.csv文件中。')
这个爬虫程序首先使用requests库发送HTTP请求并获取到网页的HTML内容
,然后使用BeautifulSoup库解析HTML页面
。然后遍历每个电影条目,并提取电影名称、评分、导演和演员等信息
。最后把提取的电影信息保存到CSV文件
中。
需要注意的是,爬虫程序必须遵守网站的爬虫规定,不得进行未经授权的数据采集或过度频繁的访问。违反网站的爬虫规定可能会导致IP封锁或其他法律问题。建议在进行爬虫程序之前仔细阅读目标网
import requests from lxml import etree import csv import time class DoubanSpider(object): def __init__(self): self.header = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/92.0.4515.131 Safari/537.36' } # 发请求 获响应 def get_source(self, com_url): res = requests.get(com_url, headers=self.header) html = res.content.decode('utf-8') return html # 解析数据 def parsed_source(self, html): tree = etree.HTML(html) divs = tree.xpath('//div[@class="info"]') # print(divs) lis_data = [] for div in divs: d = {} # 标题 title = div.xpath('./div[@class="hd"]/a/span/text()')[0].strip() # print(title) # 评分 score = div.xpath('./div[@class="bd"]/div[@class="star"]/span[@class="rating_num"]/text()')[0].strip() # print(score) # 评价人数 evaluate = div.xpath('./div[@class="bd"]/div[@class="star"]/span[last()]/text()')[0].strip() # print(evaluate) # 引用 quote = div.xpath('./div[@class="bd"]/p[@class="quote"]/span/text()') if quote: quote = quote[0] else: quote = '' # 电影链接url link_url = div.xpath('./div[@class="hd"]/a/@href')[0].strip() # print(link_url) # 根据key值提取数据 d['title'] = title d['score'] = score d['evaluate'] = evaluate d['quote'] = quote d['link_url'] = link_url lis_data.append(d) # print(lis_data) return lis_data # 保存数据 def save_source(self, move_data, header): with open('movie_data.csv', 'a', encoding='utf-8-sig', newline='') as f: w = csv.DictWriter(f, header) # 写入表头 w.writeheader() # writerows 一次性写入多行数据 w.writerows(move_data) # 主函数 def main(self): start = int(input('输入要爬取的起始页:')) end = int(input('输入要爬取的末尾页:')) for i in range(start, end+1): time.sleep(2) page = (i-1) * 25 com_url = 'https://movie.douban.com/top250?start=' + str(page) h = self.get_source(com_url) # print(h) print('爬虫机器人正在爬取第%d页' % i) move_data = self.parsed_source(h) # 设置表头 header = ['title', 'score', 'evaluate', 'quote', 'link_url'] # print(move_data) self.save_source(move_data, header) if __name__ == '__main__': # 实例化对象 Spider = DoubanSpider() # 主函数调用 Spider.main()
🌟 我的故事
python学习之路任重而道远,要想学完说容易也容易,说难也难。 很多人说python最好学了,但扪心自问,你会用python做什么了?
刚开始在大学学习c语言,写一个飞行棋的小游戏,用dos界面来做,真是出力不讨好。 地图要自己一点一点画出来,就像这样:
================ | | | | |===============
从此讨厌编程,不想继续学下去。每次作业应付。 算法考试,数据结构考试随便背代码,只求通过。 最后呢?我学会变成了吗?只能对一些概念侃侃而谈,但真的会几行代码,能写出实用工具吗? 答案变得模糊。 所以我们要从现在开始,学好python,不要再糊弄下去!!!