使用 Python线程池 爬取荣耀社区论坛评论及用户信息
在这篇博客中,我将分享如何使用 Python 爬取荣耀社区论坛的评论及其用户信息,并将这些数据保存到 CSV 文件中。这个项目通过 requests
发送 HTTP 请求,使用 lxml
解析 HTML 内容,最后使用 csv
将数据写入文件。爬虫使用 ThreadPoolExecutor
进行多线程操作,以提高抓取效率。
一、项目背景
荣耀社区是一个讨论荣耀手机及其周边产品的论坛,用户可以在上面发布帖子和评论。通过爬取这些数据,我们可以分析用户的活跃度、互动情况等指标,为用户行为分析提供数据支持。
二、环境准备
首先,确保你已经安装了以下 Python 库:
requests
: 用于发送 HTTP 请求。lxml
: 用于解析 HTML 内容。csv
: 用于保存数据到 CSV 文件。
可以通过以下命令安装所需库:
pip install requests lxml
三、代码实现
我们将代码分成几个部分来讲解,分别是获取页面详情 URL、获取评论、获取用户信息以及保存数据到 CSV 文件。
1. 获取页面详情 URL
首先,我们从论坛的每一页中提取所有帖子的详情页面 URL。
import requests
from lxml import etree
from urllib import parse
from concurrent.futures import ThreadPoolExecutor
def get_details_page_url(page_url):
res = requests.get(page_url)
url_list = tree.xpath('//div[@id="threadlisttableid"]/div')
for d_url in url_list:
details_url = d_url.xpath('.//div[@class="thdpp-cont"]/a/@href')[0]
这里,我们使用 requests.get
获取页面内容,通过 lxml.etree
将其解析为树结构,使用 xpath
定位每个帖子的链接。
2. 获取评论内容
从帖子的详情页中,我们抓取评论内容及相关的用户信息。
def get_comments(details_url):
res = requests.get(details_url)
tree = etree.HTML(res.text)
for comments in comments_list:
ids = comments.get('id')
if ids is not None and any(char.isdigit() for char in ids):
ids = ids.split("_")[-1]
try:
except:
continue
if comment != "":
user_url = tree.xpath(f'//*[@id="pid{ids}"]//a/@href')[2]
在这个部分,我们同样使用 xpath
提取页面中的评论内容和评论用户的链接。注意,异常处理在爬虫中非常重要,这里使用 try-except
来确保即使遇到错误也能继续执行。
3. 获取用户信息并保存到 CSV 文件
从用户的详情页中,我们获取用户的相关信息,并将其保存到 CSV 文件中。
import csv
import os
def get_user_info(user_url, comment):
res = requests.get(user_url)
tree = etree.HTML(res.text)
user_name = tree.xpath('//*[@id="wp"]/div[2]/div[1]/h1/text()')[0]
t_num = tree.xpath('//ul[@class="pcb-sum"]/li/span/text()')[0]
h_num = tree.xpath('//ul[@class="pcb-sum"]/li/span/text()')[1]
file_exists = os.path.isfile('荣耀社区评论内容和评论用户网页信息.csv')
with open('荣耀社区评论内容和评论用户网页信息.csv', mode='a', encoding='utf-8', newline='') as f:
writer = csv.writer(f)
if not file_exists:
writer.writerow(['用户名', 'UID', '评论内容', '发帖数', '活跃值', '勋章数量', '评论数量', '好友数量'])
writer.writerow([user_name, uid, comment, t_num, h_num, len(xz), conm_num, fri_num])
print('已保存csv')
这里我们提取了用户的用户名、UID、发帖数、活跃值、勋章数量、评论数量和好友数量,并保存到 CSV 文件中。通过检查文件是否存在来决定是否需要写入表头。
4. 多线程爬取
为了提高爬取效率,我们使用 ThreadPoolExecutor
进行多线程操作。
if __name__ == '__main__':
with ThreadPoolExecutor(max_workers=200) as executor:
for i in range(1, 1475):
url = f'https://club.hihonor.com/cn/forum-3965-11900-{i}.html?filter=lastpost'
executor.submit(get_details_page_url, url)
executor.shutdown(wait=True)
在这个主函数中,我们生成了 1474 个页面 URL,并使用 ThreadPoolExecutor
提交任务,使得多个页面可以并行处理,从而加快了爬取速度。
爬取的数据结构
四、总结
通过这个项目,我们实现了从荣耀社区论坛爬取评论及用户信息的功能,并将数据保存到 CSV 文件中。这个项目展示了如何使用 Python 的 requests
和 lxml
进行网页数据抓取,以及如何使用 csv
模块保存数据。通过多线程加速了爬取过程,使得整个过程更加高效。
最后,提醒大家在进行爬虫操作时要遵守目标网站的爬虫规则,并合理设置爬取频率以避免给服务器带来过大负载。