爬取boss直聘上海市人工智能招聘信息+LDA主题建模

news2025/1/9 22:04:41

爬取boss直聘上海市人工智能招聘信息

import time
import tqdm
import random
import requests
import json
import pandas as pd
import os
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

用edge模拟登录boss网站

browser = webdriver.Edge()
time.sleep(5)
browser.get('https://www.zhipin.com/web/geek/job?query=%E6%99%BA%E8%83%BD&city=101020100&page=1')

设置搜索的网站,然后遍历每个列表的网站元素,获取url

base_url = 'https://www.zhipin.com/web/geek/job?query=%E6%B7%B1%E5%BA%A6%E5%AD%A6%E4%B9%A0%E5%AE%9E%E4%B9%A0%E7%94%9F&city=101020100&page={}'

max_clicks = 10  # 设置最大点击次数
click_count = 1  # 记录已经点击的次数
urls = []

while click_count <= max_clicks:
    page_url = base_url.format(click_count)
    browser.get(page_url)
    time.sleep(8)
    try:
        li_list = browser.find_elements_by_xpath('//div[@class="search-job-result"]/ul/li')
        for li in li_list:
            link_element = li.find_element_by_xpath('.//div[@class="job-card-body clearfix"]')
            link_element=link_element.find_element_by_tag_name('a')
            link_href = link_element.get_attribute('href')
            print(link_href)
            urls.append(link_href)
    except Exception as e:
        print("Exception occurred:", str(e))
    click_count += 1  # 增加点击次数计数器
df = pd.DataFrame({'url': urls})
df.to_csv("./urls.csv", index=False)

遍历刚爬取的网页,用xpath语句定位招聘信息

contents=[]
df=pd.read_csv(r'urls5.csv')
for index, row in df.iterrows():
    url = row['url']  
    try:
        browser.get(url)
        print(url)
        time.sleep(6)
        content_e=browser.find_element_by_xpath('//div[@class="job-detail"]')
        content_e=content_e.find_element_by_xpath('.//div[@class="job-detail-section"]')
        content_e=content_e.find_element_by_xpath('.//div[@class="job-sec-text"]').text
        print(content_e)
        contents.append(content_e)
    except:
        pass
df_=pd.DataFrame({'content': contents})
df_.to_excel(r'招聘信息5.xlsx',index=False)

LDA主题建模

数据集为爬取的boss直聘上海市的人工智能相关岗位招聘信息。

import numpy as np
import jieba
from sklearn.feature_extraction.text import TfidfVectorizer
import pandas as pd
from sklearn.feature_extraction.text import CountVectorizer
from sklearn.decomposition import LatentDirichletAllocation
import matplotlib.pyplot as plt
# from gensim.models.word2vec import Word2Vec
import matplotlib
from pylab import xticks,yticks,np
import  time
from sklearn.feature_extraction.text import  CountVectorizer
from sklearn.decomposition import LatentDirichletAllocation
import warnings
from gensim import corpora, models
from gensim.models import CoherenceModel
warnings.filterwarnings("ignore")
import codecs
import re
import pyLDAvis.gensim
from gensim.models import LdaModel
import pandas as pd
from gensim.corpora import Dictionary
from gensim import corpora, models
# pip install gensim,re,jieba,pylab
# #这里注意gensim的版本要一致,如果报错请查看网上教程

1 读入数据,文本清洗(去除非中文字符,将只有1个字符的数据删除,删除重复行)

df = pd.read_csv(r"招聘信息.csv")
def extract_chinese(text):
    chinese_pattern = re.compile(r'[\u4e00-\u9fa5]+') 
    chinese_words = chinese_pattern.findall(text)  
    return ' '.join(chinese_words)  

df['content'] = df['content'].apply(extract_chinese)
df['content'] = df['content'].apply(lambda x: ' '.join([word for word in x.split() if len(word) > 1]))
df.drop_duplicates(inplace=True)
df.head()

这边还可以通过snownlp库进行简单的情感分类

from snownlp import SnowNLP

# 定义情感分类函数
def classify_sentiment(sentiment):
    if sentiment >= 0.5:
        return 'positive'
    else:
        return 'negative'
    
def classify_sentiments(text):
    s = SnowNLP(text)
    sentiment = s.sentiments
    return sentiment
# 对评论列进行情感分类
df['sentiment'] = df['content'].apply(classify_sentiments)
def classify_sentiment(sentiment_value):
    if sentiment_value > 0.5:
        return '正向'
    else:
        return '负向'

# 应用分类函数
df['情感类型'] = df['sentiment'].apply(classify_sentiment)
content = df['content'].values.tolist()
content[:5]

2 开启jieba分词

import jieba
segment=[]
for line in content:
    try:
        segs = jieba.lcut(line)#分词
        for seg in segs:
            if len(seg)>1 and seg != '\r\n':
                segment.append(seg)
    except:
        print(line)
        continue
segment[:10]

3 应用停用词表

np.recfromtxt(r'./stop_words.utf8',encoding='utf-8')
words_df=pd.DataFrame({'segment':segment})
stopwords = np.recfromtxt(r'./stop_words.utf8',encoding='utf-8')
words_df = words_df[~words_df.segment.isin(stopwords)]
words_df.head()
words_df.head(20)
words_stat=words_df.groupby(by=['segment'])['segment'].agg([("计数",np.size)])
words_stat=words_stat.reset_index().sort_values(by=["计数"],ascending=False)
words_stat.head()
words_stat.iloc[4]

4 文本词云图

from wordcloud import WordCloud
import matplotlib.pyplot as plt
from PIL import Image
mask_pic = np.array(Image.open(r"./1234.jpeg"))
wordcloud = WordCloud(width=300, height=200,scale=4,mask=mask_pic,font_path='simhei.ttf',background_color='white',max_font_size=80)
word_frequence = {x[0]:x[1] for x in words_stat.head(220).values}
wordcloud=wordcloud.fit_words(word_frequence)
plt.axis('off')
image = wordcloud.to_image()
wordcloud.to_file('词云.png')  # 保存图片
image.show()
words_stat.to_csv(r'文本频率表.csv',index=False)

5 TF_IDF词语权重表

comments = content
segmented_comments = []
for comment in comments:
    words = jieba.cut(comment)
    filtered_words = [word for word in words if word not in stopwords]
    segmented_comments.append(" ".join(filtered_words))
tfidf_vectorizer = TfidfVectorizer(max_features=1000)

# 使用评论数据拟合TF-IDF向量化器并转换数据
tfidf_matrix = tfidf_vectorizer.fit_transform(segmented_comments)

# 获取特征词列表
feature_names = tfidf_vectorizer.get_feature_names_out()

# 将TF-IDF矩阵转换为DataFrame,并加上特征词作为列名
tfidf_df = pd.DataFrame(tfidf_matrix.toarray(), columns=feature_names)

# 计算每个特征词的平均TF-IDF权重
avg_tfidf = tfidf_df.mean().sort_values(ascending=False)
print(avg_tfidf)
avg_tfidf.to_csv(r'./词语权重表.csv')

 6 LDA建模曲线图 

stop_words_file = './stop_words.utf8'
stop_words = set()
with codecs.open(stop_words_file, 'r', 'utf-8') as f:
    for word in f:
        stop_words.add(word.strip())
texts = [list(filter(lambda x: x not in stop_words, jieba.cut(text.replace(" ", "").strip()))) for text in content]
dictionary = corpora.Dictionary(texts)
corpus = [dictionary.doc2bow(text) for text in texts]
def lda_model_values(num_topics, corpus, dictionary):
    x = [] # x轴
    perplexity_values = [] # 困惑度
    coherence_values = []  # 一致性
    model_list = [] # 存储对应主题数量下的lda模型,便于生成可视化网页
    for topic in range(num_topics):
        print("主题数量:", topic+1)
        lda_model = models.LdaModel(corpus=corpus, num_topics=topic+1, id2word =dictionary, chunksize = 2000, passes=20, iterations = 400)
        model_list.append(lda_model)
        x.append(topic+1)
        perplexity_values.append(lda_model.log_perplexity(corpus))
        coherencemodel = models.CoherenceModel(model=lda_model, texts=texts, dictionary=dictionary, coherence='c_v')
        coherence_values.append(coherencemodel.get_coherence())
        print("该主题评价完成\n")
    return model_list, x, perplexity_values, coherence_values
# 调用准备函数
model_list, x, perplexity_values, coherence_values = lda_model_values(8, corpus, dictionary) 

# 绘制困惑度和一致性折线图
fig = plt.figure(figsize=(15,5))
plt.rcParams['font.sans-serif']=['SimHei']
matplotlib.rcParams['axes.unicode_minus'] = False 
ax1 = fig.add_subplot(1, 2, 1)
plt.plot(x, perplexity_values, marker="o")
plt.title("主题建模-困惑度")
plt.xlabel('主题数目')
plt.ylabel('困惑度大小')
xticks(np.linspace(1, 8,8, endpoint=True)) # 保证x轴刻度为1

ax2 = fig.add_subplot(1, 2, 2)
plt.plot(x, coherence_values, marker="o")
plt.title("主题建模-一致性")
plt.xlabel("主题数目")
plt.ylabel("一致性大小")
xticks(np.linspace(1,8,8 ,endpoint=True))

plt.show()

# plt.savefig('主题建模一致性_困惑度曲线.png')

 7 LDA气泡图 

lda = LdaModel(corpus=corpus, id2word=dictionary, num_topics=3, passes = 10,random_state=42)
#将这里的num_topics换成上述观测到的最佳建模主题数,数值应该取困惑度小同时一致性高的拐点,注意纵坐标!!!
#每次生成的曲线图和LDA气泡图可能不一样,因为该算法为无监督算法,所以每次训练的语料不一样
topic_list=lda.print_topics()
print(topic_list)
 
result_list =[]
for i in lda.get_document_topics(corpus)[:]:
    listj=[]
    for j in i:
        listj.append(j[1])
    bz=listj.index(max(listj))
    result_list.append(i[bz][0])
print(result_list)
topic_data = pd.DataFrame(columns=['主题', '关键词', '概率分数'])

for topic in topic_list:
    topic_num, topic_terms = topic
    terms = topic_terms.split('+')
    for term in terms:
        probability, word = term.split('*')
        word = word.strip()
        probability = probability.strip()
        topic_data = pd.concat([topic_data, pd.DataFrame({'主题': [topic_num], '关键词': [word], '概率分数': [probability]})], ignore_index=True)
topic_data = topic_data.groupby('主题')['关键词'].apply(lambda x: ' '.join(x)).reset_index()
topic_data['关键词'] = topic_data['关键词'].replace('"', '', regex=True)

# 将 DataFrame 导出到 Excel 文件
topic_data.to_excel('主题关键词概率分数.xlsx', index=False)
pyLDAvis.enable_notebook()
data = pyLDAvis.gensim.prepare(lda, corpus, dictionary)
pyLDAvis.save_html(data, './topic.html')

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

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

相关文章

【STM32+HAL】FreeRTOS学习小札

一、RTOS程序任务结构 如上图所示&#xff0c;在实时操作系统中&#xff0c;开发人员可以把要实现的功能划分为多个任务&#xff0c;每个任务负责实现其中的一部分&#xff0c;每个任务都是一个很简单的程序&#xff0c;通常是一个死循环。 二、多任务系统基本概念 1、FreeRTO…

路径规划之启发式算法之二:遗传算法(Genetic Algorithm)

遗传算法&#xff08;Genetic Algorithm, GA&#xff09;是一种基于自然选择和遗传学原理的优化搜索算法&#xff0c;它通过模拟自然界的进化过程来寻找最优解。 一、基本原理 遗传算法的基本原理是模拟自然选择、遗传和突变等生物进化过程。它通过将问题的求解过程转换成类似…

【ubuntu24.04】GTX4700 配置安装cuda

筛选显卡驱动显卡驱动 NVIDIA-Linux-x86_64-550.135.run 而后重启:最新的是12.6 用于ubuntu24.04 ,但是我的4700的显卡驱动要求12.4 cuda

Springboot的文件上传与下载

Springboot的文件上传与下载 文章说明配置路径映射实体类、服务与控制器前端页面前端服务器搭建 文章说明 文件上传实现了&#xff0c;文件下载是非常简单的&#xff0c;只需要通过浏览器即可下载成功&#xff1b;于是就没有实现专门的接口 配置路径映射 通过 public void addR…

多方法做配对样本t检验(三)

Wilcoxon符号秩检验 Wilcoxon符号秩检验&#xff08;Wilcoxon Signed-Rank Test&#xff09; 是一种非参数统计方法&#xff0c;用于检验两组相关样本&#xff08;配对样本&#xff09;之间的差异是否显著。它通常用来代替配对样本t检验&#xff0c;特别是在数据不符合正态分布…

如何选择最适合企业的ETL解决方案?

在今天的大数据时代&#xff0c;企业的数据管理和处理变得愈发重要。企业也越来越依赖于数据仓库和数据湖来提取、转换和加载&#xff08;ETL&#xff09;关键业务信息。一个高效、灵活的ETL解决方案不仅能提升数据处理能力&#xff0c;还能为企业决策提供有力支持。然而&#…

前端node.js

一.什么是node.js 官网解释:Node.js 是一个开源的、跨平台的 JavaScript 运行时环境。 二.初步使用node.js 需要区分开的是node.js和javascript互通的只有console和定时器两个API. 三.Buffer Buffer 是一个类似于数组的 对象&#xff0c;用于表示固定长度的字节序列。Buffer…

Facebook的开源项目解析:推动开发者社区的技术进步

Facebook&#xff0c;作为全球领先的社交平台之一&#xff0c;其在技术领域的创新不仅体现在产品功能的实现上&#xff0c;也积极推动开源社区的发展。开源项目已经成为Facebook技术战略的重要组成部分&#xff0c;通过开源&#xff0c;Facebook不仅加速了技术进步&#xff0c;…

本地学习axios源码-如何在本地打印axios里面的信息

1. 下载axios到本地 git clone https://github.com/axios/axios.git 2. 下载react项目, 用vite按照提示命令配置一下vite react ts项目 npm create vite my-vue-app --template react 3. 下载koa, 搭建一个axios请求地址的服务端 a.初始化package.json mkdir koa-server…

电阻可靠性的内容

一、影响电阻可靠性的因素&#xff1a; 影响电阻可靠性的因素有温度系数、额定功率&#xff0c;最大工作电压、固有噪声和电压系数 &#xff08;一&#xff09;温度系数 电阻的温度系数表示当温度改变1摄氏度时&#xff0c;电阻阻值的相对变化&#xff0c;单位为ppm/℃.电阻温…

uniapp联系我们页的设计和实现

联系我们页 代码 map文档&#xff1a;map | uni-app官网 (dcloud.net.cn) <template><view class"contact"><image class"img" src"http://www.itcast.cn/2018czydz/images/gywmban.jpg"></image><view class"…

算法竞赛进阶指南——位运算

算法竞赛进阶指南——位运算 与或非异或and&#xff0c;&or&#xff0c;|not&#xff0c;~xor&#xff0c;^ 在m位二进制数中&#xff0c;通常称最低位为第0位&#xff0c;从右到左以此类推&#xff0c;最高位是第m-1位 补码&#xff1a; unsigned int&#xff1a; 直接把…

【科研】9如何高效阅读和理解学术论文

【科研】9如何高效阅读和理解学术论文 写在最前面一、为什么需要系统的阅读方法&#xff1f;二、阅读论文的11步方法三、实践示例四、常见问题解答五、结语 &#x1f308;你好呀&#xff01;我是 是Yu欸 &#x1f30c; 2024每日百字篆刻时光&#xff0c;感谢你的陪伴与支持 ~ …

Java 泛型详细解析

泛型的定义 泛型类的定义 下面定义了一个泛型类 Pair&#xff0c;它有一个泛型参数 T。 public class Pair<T> {private T start;private T end; }实际使用的时候就可以给这个 T 指定任何实际的类型&#xff0c;比如下面所示&#xff0c;就指定了实际类型为 LocalDate…

Design Linear Filters in the Frequency Domain (MATLAB帮助文档)

Design Linear Filters in the Frequency Domain 这个帮助文档写得很好&#xff0c;简单明了&#xff0c;一句废话没有。 This topic describes functions that perform filtering in the frequency domain. 2-D Finite Impulse Response (FIR) Filters The Image Processi…

手机实时提取SIM卡打电话的信令声音-蓝牙电话如何适配eSIM卡的手机

手机实时提取SIM卡打电话的信令声音 --蓝牙电话如何适配eSIM卡的手机 一、前言 蓝牙电话的海外战略中&#xff0c;由于海外智能手机市场中政策的差异性&#xff0c;对内置eSIM卡的手机进行支持是非常合理的需求。Android系列手机中&#xff0c;无论是更换通信运营商&#xf…

软通动力携子公司鸿湖万联、软通教育助阵首届鸿蒙生态大会成功举办

11月23日中国深圳&#xff0c;首届鸿蒙生态大会上&#xff0c;软通动力及软通动力子公司鸿湖万联作为全球智慧物联网联盟&#xff08;GIIC&#xff09;理事单位、鸿蒙生态服务&#xff08;深圳&#xff09;有限公司战略合作伙伴&#xff0c;联合软通教育深度参与了大会多项重磅…

【论文笔记】Frequency Domain Model Augmentation for Adversarial Attack

Abstract 对于黑盒攻击&#xff0c;替代模型与受害模型之间的差距通常较大&#xff0c;表现为较弱的攻击性能。基于对抗样本的可迁移性可以通过同时攻击不同模型来提高的观察&#xff0c;提出了利用变换图像模拟不同模型的模型增强方法。 然而&#xff0c;现有的空间域变换并没…

【人工智能-科普】深度森林:传统机器学习与深度学习的创新结合

文章目录 深度森林:传统机器学习与深度学习的创新结合一、什么是深度森林?二、深度森林的工作原理1. **特征提取和转换**2. **多层级训练**3. **最终分类**三、深度森林的关键组成部分1. **森林层(Forest Layer)**2. **级联结构(Cascade Structure)**3. **特征增强(Feat…

嵌入式硬件实战提升篇(三)商用量产电源设计方案 三路电源输入设计 电源管理 多输入供电自动管理 DCDC降压

引言&#xff1a;本文你能实际的了解到实战量产产品中电源架构设计的要求和过程&#xff0c;并且从实际实践出发搞懂电源架构系统&#xff0c;你也可以模仿此架构抄板到你自己的项目&#xff0c;并结合硬件篇之前的项目以及理论形成正真的三路电源输入设计与开发板电源架构块供…