之前文中有人提到:想要一个简单易用、能快速实现多线程爬虫的方案,而且目标是小网站,基本可以确定对反爬虫措施要求不高,这些就比较简单了。
以往我肯定要考虑常见的编程语言中哪些适合爬虫。Python、JavaScript(Node.js)、Go、Java这些应该都是候选。因为需要省事,所以可能更倾向于语法简单、库丰富的语言。
Python的话,有requests和Scrapy框架,还有aiohttp做异步。多线程的话,Python的threading模块可能因为GIL限制效率,但如果是IO密集型任务,比如网络请求,多线程还是有效的。不过异步可能更好,比如asyncio,但用户明确说多线程,可能需要用concurrent.futures的ThreadPoolExecutor。Python的优点是库多,代码简洁,适合小项目,省时间。
针对多线程爬取小网站的需求,推荐以下语言和方案,按优先级排序:
requests/aiohttp + BeautifulSoup/parsel 组合开箱即用。concurrent.futures.ThreadPoolExecutor 两行代码实现线程池。goroutine + channel 轻松管理百万级并发。net/http + goquery 满足基础需求。axios + cheerio 类似前端开发体验。Promise.all 或 worker_threads 实现真并行。time.sleep(1)),避免触发封禁。robots.txt,避免敏感数据抓取。现在我以 Python 为例,手把手教你写一个多线程爬虫,10分钟即可跑通,适合新手快速上手。
网址:
https://movie.douban.com/top250
pip install requests parsel concurrent-log-handler # 核心库:请求 + 解析 + 线程池import requests
from parsel import Selector
from concurrent.futures import ThreadPoolExecutor
import time
# 伪装浏览器 + 全局Headers
HEADERS = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36"
}
def scrape_page(url):
"""爬取单个页面"""
try:
response = requests.get(url, headers=HEADERS, timeout=5)
response.raise_for_status() # 自动识别HTTP错误(如404)
return response.text
except Exception as e:
print(f"请求失败: {url} | 错误: {e}")
return None
def parse_data(html):
"""解析页面数据"""
selector = Selector(html)
movies = []
for item in selector.css(".item"):
title = item.css(".title::text").get()
rating = item.css(".rating_num::text").get()
movies.append({"title": title, "rating": rating})
return movies
def worker(page):
"""线程任务函数:处理单页"""
url = f"https://movie.douban.com/top250?start={(page-1)*25}"
html = scrape_page(url)
if html:
movies = parse_data(html)
print(f"第{page}页爬取完成,共{len(movies)}部电影")
return movies
return []
def main():
# 创建线程池(限制为5线程,避免封IP)
with ThreadPoolExecutor(max_workers=5) as executor:
# 提交25页任务(豆瓣Top250共10页,这里测试用3页)
futures = [executor.submit(worker, page) for page in range(1, 4)]
# 等待所有任务完成并合并结果
all_movies = []
for future in futures:
all_movies.extend(future.result())
time.sleep(1) # 每页间隔1秒,降低被封风险
# 打印结果
print("\n===== 爬取结果 =====")
for movie in all_movies:
print(f"《{movie['title']}》 评分:{movie['rating']}")
if __name__ == "__main__":
main()HEADERS模拟Chrome浏览器,绕过基础反爬。ThreadPoolExecutor自动管理线程,max_workers=5限制并发数。executor.submit提交页码(1~3页)到线程池。time.sleep(1))。scrape_page中捕获超时、HTTP错误等,避免程序崩溃。第1页爬取完成,共25部电影
第2页爬取完成,共25部电影
第3页爬取完成,共25部电影
===== 爬取结果 =====
《肖申克的救赎》 评分:9.7
《霸王别姬》 评分:9.6
《阿甘正传》 评分:9.5
...
(共75条数据)requests.get中添加proxies参数应对封IP。aiohttp + asyncio实现更高并发。with open('movies.json', 'w')保存结果。selenium或playwright。pytesseract)。最后适合不适合就得结合自己的项目,尝试跑起来看看吧!遇到问题随时调整线程数和间隔时间即可~
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。