多线程股吧(东方财富)用户信息爬取

多线程东方财富(股吧)用户信息爬取

在上一篇博客股吧信息爬取的基础上加入了多线程,使得速度提升了十几倍,爬取内容如下:
在这里插入图片描述
最终爬取结果如下:
在这里插入图片描述

完整代码如下(准备好环境,比如python的第三方库之后可以直接运行):

import csv
import random
import re
import threadingimport chardet
import pandas as pd
from bs4 import BeautifulSoup
from selenium import webdriver
import concurrent.futures
from datetime import datetime
from tqdm import tqdm
from urllib.parse import urljoin
import requestschrome_options = webdriver.ChromeOptions()
# 添加其他选项,如您的用户代理等
# ...
chrome_options.add_argument('--headless')  # 无界面模式,可以加速爬取
# 指定 Chrome WebDriver 的路径
driver = webdriver.Chrome(executable_path='/usr/local/bin/chromedriver', options=chrome_options)
## 浏览器设置选项
# chrome_options = Options()
chrome_options.add_argument('blink-settings=imagesEnabled=false')def get_time():"""获取随机时间"""return round(random.uniform(3, 6), 1)from random import choicedef get_user_agent():"""获取随机用户代理"""user_agents = ["Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; SV1; AcooBrowser; .NET CLR 1.1.4322; .NET CLR 2.0.50727)",# "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 6.0; Acoo Browser; SLCC1; .NET CLR 2.0.50727; Media Center PC 5.0; .NET CLR 3.0.04506)",# "Mozilla/4.0 (compatible; MSIE 7.0; AOL 9.5; AOLBuild 4337.35; Windows NT 5.1; .NET CLR 1.1.4322; .NET CLR 2.0.50727)","Mozilla/5.0 (Windows; U; MSIE 9.0; Windows NT 9.0; en-US)",# "Mozilla/5.0 (iPod; U; CPU iPhone OS 2_1 like Mac OS X; ja-jp) AppleWebKit/525.18.1 (KHTML, like Gecko) Version/3.1.1 Mobile/5F137 Safari/525.20",# "Mozilla/5.0 (Linux;u;Android 4.2.2;zh-cn;) AppleWebKit/534.46 (KHTML,like Gecko) Version/5.1 Mobile Safari/10600.6.3 (compatible; Baiduspider/2.0; +http://www.baidu.com/search/spider.html)","Mozilla/5.0 (compatible; Baiduspider/2.0; +http://www.baidu.com/search/spider.html)"]## 在user_agent列表中随机产生一个代理,作为模拟的浏览器user_agent = choice(user_agents)return user_agentdef get_page(list_url):"""获取包含特定关键字的留言链接"""user_agent = get_user_agent()headers = {'User-Agent': user_agent}# Make the request using the requests libraryresponse = requests.get(list_url, headers=headers)if response.status_code == 200:html_content = response.text# 使用 BeautifulSoup 解析 HTMLsoup = BeautifulSoup(html_content, 'html.parser')bump_elements = soup.find_all(class_='nump')# 提取数字并转换为整数nump_numbers = [int(element.text) for element in bump_elements]# 找出最大的数if nump_numbers:max_nump = max(nump_numbers)else:# 处理空序列的情况,例如给 max_nump 赋一个默认值max_nump = None  # 或者其他你认为合适的默认值return max_numpelse:print(f"Error: {response.status_code}")return Nonedef generate_urls(base_url, page_number, total_pages):urls = []for page in range(2, total_pages + 1, page_number):url = f"{base_url},f_{page}.html"urls.append(url)return urlsdef get_detail_urls_by_keyword(urls):comment, link, reads, date = [], [], [], []total_iterations = len(urls)# Create a tqdm instance for the progress barprogress_bar = tqdm(total=total_iterations, desc='Processing URLs', position=0, leave=True)# 在函数外定义一个锁lock = threading.Lock()def process_url(url):nonlocal comment, link, reads, date'''获取包含特定关键字的留言链接'''user_agent = get_user_agent()headers = {'User-Agent': user_agent}# Make the request using the requests libraryresponse = requests.get(url, headers=headers)encoding = chardet.detect(response.content)['encoding']# 解码响应内容if response.status_code == 200:html_content = response.content.decode(encoding)# 使用 BeautifulSoup 解析 HTMLsoup = BeautifulSoup(html_content, 'html.parser')#print(html_content)# Extract and convert relative URLs to absolute URLswith lock:links = []author_elements = soup.select('div.author a')for element in author_elements:href = element.get('href')if href:absolute_url = urljoin('https:', href)links.append(absolute_url)links = ['https://i.eastmoney.com/' + text.split('"//i.eastmoney.com/')[-1].split('">')[0] for text inlinks]link = [link[len('https://i.eastmoney.com/'):] if link.startswith('https://i.eastmoney.com/') else link forlink in links]# Extract commentscomment_elements = soup.select('div.reply')for element in comment_elements:message_id = element.text.strip().split(':')[-1]comment.append(message_id)# Extract datespattern = re.compile(r'\d{1,2}-\d{1,2} \d{2}:\d{2}')# Find all matches in the textdate = pattern.findall(html_content)# Extract readsread_elements = soup.select('div.read')for element in read_elements:message_id = element.text.strip().split(':')[-1]reads.append(message_id)# Update the progress barprogress_bar.update(1)else:print(f"Error: {response.status_code}")# Create threads for each URLthreads = []for url in urls:thread = threading.Thread(target=process_url, args=(url,))thread.start()threads.append(thread)# Wait for all threads to completefor thread in threads:thread.join()# Close the progress barprogress_bar.close()return comment, link, reads, datedef extract_and_combine(url):match = re.search(r'\d{6}', url)if match:extracted_number = match.group()result = extracted_numberreturn resultelse:return Nonedef process_dates(date_list):processed_dates = []current_year = 2023for date_str in date_list:try:# Adjust the format string based on the actual format of your datadate_obj = datetime.strptime(date_str, "%m-%d %H:%M")# Check if processed_dates is not empty before accessing its last elementif processed_dates and date_obj.month < processed_dates[-1].month:current_year -= 1# Replace the year in date_obj with the updated current_yearprocessed_date = date_obj.replace(year=current_year)processed_dates.append(processed_date)except ValueError as e:print(f"Error processing date '{date_str}': {e}")return processed_datesdef write_to_csv_file(comment, link, reads, date, result):"""将数据写入 CSV 文件Parameters:comment (list): 评论数列表link (list): 链接列表title (list): 标题列表reads (list): 阅读数列表date (list): 日期列表result (str): 结果标识Returns:None"""# 指定 CSV 文件的路径csv_file_path = result + "_评论.csv"# 将数据写入 CSV 文件with open(csv_file_path, 'w', newline='', encoding='utf-8') as csv_file:csv_writer = csv.writer(csv_file)# 写入表头csv_writer.writerow(['评论数', '链接', '阅读数', '日期'])# 写入数据csv_writer.writerows(zip(comment, link, reads, date))print(f"CSV 文件已生成: {csv_file_path}")def filter_and_append_links(comment, link):"""过滤评论数大于等于0的链接并添加到 final_link 列表中Parameters:comment (list): 包含评论数的列表link (list): 包含链接的列表Returns:final_link (list): 过滤后的链接列表"""final_link = []for i in range(4, len(link)):comment_value = int(comment[i])if comment_value >= 0:final_link.append(link[i])return final_linkdef remove_duplicates(input_list):unique_list = []for item in input_list:if item not in unique_list:unique_list.append(item)return unique_listdef process_result_links(links):# 调用去重函数result_link = remove_duplicates(links)# 使用循环和 remove 方法移除包含子列表的元素for item in result_link[:]:  # 使用切片创建副本,以防止在循环中修改原始列表if 'list' in item:result_link.remove(item)return result_linkdef get_information_for_url(url):influence, age, location, fan = [], [], [], []user_agent = get_user_agent()headers = {'User-Agent': user_agent}# Make the request using the requests libraryresponse = requests.get(url, headers=headers)if response.status_code == 200:html_content = response.text# 使用 BeautifulSoup 解析 HTMLprint(html_content)soup = BeautifulSoup(html_content, 'html.parser')# 提取影响力信息# Extract agesage_elements = soup.select('div.others_level p:contains("吧龄") span')for element in age_elements:age_text = element.text.strip()age.append(age_text)# Extract locationslocation_elements = soup.select('p.ip_info')for element in location_elements:text = element.text.strip()match = re.search(r':([^?]+)\?', text)if match:ip_location = match.group(1)location.append(ip_location)# Extract fansfan_elements = soup.select('div.others_fans a#tafansa span.num')for element in fan_elements:message_id = element.text.strip().split(':')[-1]fan.append(message_id)return influence, age, location, fanelse:print(f"Error: {response.status_code}")return Nonedef get_information(urls):influence, age, location, fan = [], [], [], []with concurrent.futures.ThreadPoolExecutor() as executor:results = list(tqdm(executor.map(get_information_for_url, urls), total=len(urls), desc="Processing URLs"))for result in results:influence.extend(result[0])age.extend(result[1])location.extend(result[2])fan.extend(result[3])return age, location, fandef write_to_csv(result_link, age, location, fan, result):# 构建 CSV 文件名csv_filename = result + "_用户.csv"# 将数据封装成字典列表data = [{"链接": link, "吧龄": a, "属地": loc, "粉丝": f}for link, a, loc, f in zip(result_link, age, location, fan)]# 使用 csv 模块创建 CSV 文件并写入数据,同时指定列名with open(csv_filename, 'w', newline='') as csvfile:fieldnames = ["链接", "吧龄", "属地", "粉丝"]writer = csv.DictWriter(csvfile, fieldnames=fieldnames)# 写入列名writer.writeheader()# 写入数据writer.writerows(data)print(f"Data has been written to {csv_filename}")def convert_to_guba_link(file_path):"""读取 Excel 文件中的六位数,将其转换为股吧链接Parameters:file_path (str): Excel 文件路径Returns:guba_links (list): 转换后的股吧链接列表"""guba_links = []try:# 读取 Excel 文件df = pd.read_excel(file_path)# 获取第一列的数据six_digit_numbers = df.iloc[:, 0]# 转换六位数为股吧链接for number in six_digit_numbers:# 使用 f-string 构建链接link = f"https://guba.eastmoney.com/list,{number:06d}.html"guba_links.append(link)except Exception as e:print(f"Error: {e}")return guba_linksdef main():"""主函数"""list_urls = convert_to_guba_link('number.xlsx')print('爬虫程序开始执行--->')i = 2for list_url in list_urls:page = 3print("总页数:",page)page_number = 1url_without_html = list_url.replace(".html", "")urls = generate_urls(url_without_html, page_number, page)print(urls)comment, link, reads, date = get_detail_urls_by_keyword(urls)print(comment)print(link)print(reads)print(date)date = process_dates(date)result = extract_and_combine(list_url)write_to_csv_file(comment, link, reads, date, result)link = process_result_links(link)age, location, fan = get_information(link)print(age)print(location)print(fan)write_to_csv(link, age, location, fan, result)print('抓取完个数:',i)i = i + 1if __name__ == '__main__':'''执行主函数'''main()

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

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

相关文章

近年来自动驾驶行业就业与企业需求情况

自动驾驶行业在近年来持续发展&#xff0c;就业情况和企业需求呈现出多样化和复杂化的趋势。 以下是基于我搜索到的资料对自动驾驶行业最新就业情况和企业需求的详细分析&#xff1a; 自动驾驶行业对高端技术人才的需求非常旺盛&#xff0c;尤其是架构工程师、算法工程师等岗…

Qt(10.8)

作业&#xff1a;完善登录界面 源文件 #include "widget.h" #include "ui_widget.h" #include<QDebug> #include<QLabel> #include<QMessageBox> Widget::Widget(QWidget *parent): QWidget(parent), ui(new Ui::Widget) {ui->setu…

【C++篇】继承之韵:解构编程奥义,领略面向对象的至高法则

文章目录 C 继承详解&#xff1a;初阶理解与实战应用前言第一章&#xff1a;继承的基本概念与定义1.1 继承的概念1.2 继承的定义 第二章&#xff1a;继承中的访问权限2.1 基类成员在派生类中的访问权限2.2 基类与派生类对象的赋值转换2.2.1 派生类对象赋值给基类对象2.2.2 基类…

leetcode68:文本左右对齐

给定一个单词数组 words 和一个长度 maxWidth &#xff0c;重新排版单词&#xff0c;使其成为每行恰好有 maxWidth 个字符&#xff0c;且左右两端对齐的文本。 你应该使用 “贪心算法” 来放置给定的单词&#xff1b;也就是说&#xff0c;尽可能多地往每行中放置单词。必要时可…

Ubuntu 22.04 安装 KVM

首先检查是否支持 CPU 虚拟化&#xff0c;现在的 CPU 都应该支持&#xff0c;运行下面的命令&#xff0c;大于0 就是支持。 egrep -c (vmx|svm) /proc/cpuinfo安装 Libvirt apt install -y qemu-kvm virt-manager libvirt-daemon-system virtinst libvirt-clients bridge-uti…

DAMA数据管理知识体系(第11章 数据仓库和商务智能)

课本内容 11.1 引言 概要 数据仓库被公认为企业数据管理的核心语境关系图 图11-1 语境关系图&#xff1a;数据仓库和商务智能业务驱动因素 运营支持职能合规需求商务智能活动目标和原则 目标 一个组织建设数据仓库的目标通常有&#xff1a; 1&#xff09;支持商务智能活动。 2&…

易图讯军用VR三维电子沙盘系统

深圳易图讯军用VR三维电子沙盘系统是一种集成了虚拟现实&#xff08;VR&#xff09;技术、三维建模技术、大数据分析、实时动态更新以及高度安全可靠的综合性军事指挥平台。该系统通过高精度三维模型真实再现战场环境&#xff0c;为指挥员提供沉浸式体验和交互操作的可能性&…

数据结构与算法——Java实现 31.阻塞队列

—— 24.10.8 一、问题提出 目前队列存在的问题 1.很多场景要求分离生产者、消费者两个角色、它们需要由不同的线程来担当&#xff0c;而之前的实现根本没有考虑线程安全问题 2.poll方法&#xff0c;队列为空&#xff0c;那么在之前的实现里会返回null&#xff0c;如果就是硬…

构建MySQL健康检查Web应用

构建MySQL健康检查Web应用 在这里将探讨如何将MySQL健康检查功能转换为一个功能完整的Web应用。这个应用允许用户通过简单的Web界面执行MySQL健康检查&#xff0c;并查看详细的结果。我们将逐步介绍代码实现、改进过程以及如何设置和运行这个应用。 1. MySQL健康检查类 首先…

codetop标签双指针题目大全解析(二),双指针刷穿地心!!!!!

复习比学习更重要&#xff0c;如果忘了就跟没学是一样的 1.和为k的子数组2.统计[优美子数组]3.区间列表的交集4.将x减到0的最小操作5.替换子串得到平衡字符串6.划分字母区间7.分隔链表8.通过删除字母匹配到字典里最长单词9.寻找目标值-二维数组10.至多包含两个不同字符的最长子…

麒麟系统串口配置篇

麒麟系统串口配置篇 1.配置串口驱动&#xff08;编译/动态加载串口&#xff09; 解压文件夹,然后在解压后的文件夹所在目录&#xff0c;右键选择打开终端&#xff0c;依次执行以下命令&#xff1a; 以麒麟系统下的CH341串口驱动为例&#xff0c;解压CH341SER_LINUX.zip sudo…

2024_10_8 系统进展

改进位置 发现是label_api里藏了我需要改进的东西 settings.py 数据库 我这边电脑上使用的是windows 192 vue.config.js 陈家强是这样设置的 module.exports {publicPath: process.env.NODE_ENV production? /: /,assetsDir: static,// css: {// extract: false// },…

【C++ 11】for 基于范围的循环

文章目录 【 1. 基本用法 】【 2. for 新格式的应用 】2.1 for 遍历字符串2.2 for 遍历列表2.3 for 遍历的同时修改元素 问题背景 C 11标准之前&#xff08;C 98/03 标准&#xff09;&#xff0c;如果要用 for 循环语句遍历一个数组或者容器&#xff0c;只能套用如下结构&#…

“我养你啊“英语怎么说?别说成I raise you!成人学英语到蓝天广场附近

“我养你啊”这句经典台词出自周星驰自导自演的电影《喜剧之王》。在这部电影中&#xff0c;周星驰饰演的尹天仇对张柏芝饰演的柳飘飘说出了这句深情而动人的台词。这句台词出现在柳飘飘即将离去之时&#xff0c;尹天仇鼓起勇气&#xff0c;用它作为对柳飘飘个人困境的承诺&…

VIP与MPIO,备胎管理谁更强

我爱上班&#xff0c;风雨无阻 大家每天去上班&#xff0c;不可能只有一条路线 可以地铁、也可以开车或公交 万一地铁停运或车子限行&#xff0c;至少还有其他线路选择 企业级存储也是如此 关键业务的存储访问一般有多条路径 网络或单个存储设备故障后 访问路径会自动切换…

集合框架05:List接口使用、List实现类、ArrayList使用

视频链接&#xff1a;13.11 ArrayList使用_哔哩哔哩_bilibilihttps://www.bilibili.com/video/BV1zD4y1Q7Fw?p11&vd_sourceb5775c3a4ea16a5306db9c7c1c1486b5 1.List接口使用代码举例 package com.yundait.Demo01;import java.util.ArrayList; import java.util.List;pu…

轻松掌握IP代理服务器设置方法,网络冲浪更自如

在数字化时代&#xff0c;互联网就像是一片浩瀚的海洋&#xff0c;而IP代理服务器就如同我们在这片海洋中航行的指南针。通过使用代理IP&#xff0c;我们可以更方便地访问全球网络资源&#xff0c;提升网络安全性。本文将为您详细介绍IP代理服务器的设置方法&#xff0c;让您在…

指针——指针数组、数组指针

&#xff08;一&#xff09;指针数组 1、本质&#xff1a;指针数组的本质任然是数组 2、基本格式&#xff1a;int* arr[5] 3、应用&#xff1a;如尝试使用指针来模拟二维数组 先来看代码 #include<stdio.h> //指针数组——模拟实现二维数组 int main() {int a[5] {…

本科毕业论文不会写怎么办,论文查重显示80%多

如果本科毕业论文不会写且查重显示 80% 多&#xff0c;可以从以下几个方面着手解决&#xff1a; 一、调整心态&#xff0c;正视问题 首先&#xff0c;不要惊慌和焦虑。高重复率并不意味着无法挽救&#xff0c;要相信自己有能力解决这个问题。把它看作是一个学习和提升的机会&a…

Matlab实现海鸥优化算法优化回声状态网络模型 (SOA-ESN)(附源码)

目录 1.内容介绍 2部分代码 3.实验结果 4.内容获取 1内容介绍 海鸥优化算法&#xff08;Seagull Optimization Algorithm, SOA&#xff09;是一种受海鸥觅食和飞行行为启发的群体智能优化算法。SOA通过模拟海鸥在空中搜寻食物、聚集和分散的行为模式&#xff0c;来探索和开发…