数据采集与融合技术综合设计

news/2024/12/16 3:13:28/文章来源:https://www.cnblogs.com/Con1427/p/18607800

职途启航

数据采集项目实践 https://edu.cnblogs.com/campus/fzu/2024DataCollectionandFusiontechnology
组名、项目简介 组别:数据矿工,项目需求:爬取招聘网站的求助信息、编辑信息匹配系统等,项目简介:根据求职者的个人信息为其推荐最合适的工作、根据全国各省的各行业信息为求职者提供合适的参考城市、项目开展技术路线:数据库操作:使用 pymysql 库与 MySQL 数据库进行交互,执行 SQL 查询和获取数据、Flask Web 框架:使用了 Flask 作为 Web 应用框架,用于创建 Web 服务和 API 端点 、WSGI 服务器 :pywsgi 作为 WSGI 服务器来运行 Flask 应用
团队成员学号 102202132郑冰智、102202131林鑫、102202143梁锦盛、102202111刘哲睿、102202122张诚坤、102202136洪金举
这个项目的目标 根据求职者的个人信息为其推荐最合适的工作
其他参考文献 https://github.com/balloonwj/CppGuide

GitHub连接:https://gitee.com/zheng-bingzhi/2022-level-data-collection/tree/master/职业规划与就业分析平台

一.项目介绍:

1.1项目背景:

随着互联网技术的飞速发展,网络招聘平台如雨后春笋般涌现,为求职者和招聘者提供了一个广阔的交流平台。然而,面对海量的招聘信息,许多求职者感到迷茫,难以判断自己的技能和经验与哪些岗位相匹配。此外,不同城市的发展重点和行业特色导致相同岗位在不同地区的薪资水平和发展前景存在显著差异。因此,一个能够提供精准职位匹配和城市行业分析的工具对于求职者来说显得尤为重要。

1.2项目目标:

本项目旨在开发一个综合性的互联网招聘服务平台,通过智能算法为求职者提供个性化的职位推荐,同时分析各省份的行业发展状况,帮助求职者做出更明智的职业选择。

1.3项目功能:

  • 1、职位智能匹配:
  • 2、利用机器学习算法分析求职者的简历和技能,与数据库中的招聘信息进行匹配,推荐最适合的工作岗位。
  • 3、城市行业分析:
  • 4、收集并分析各省份的主要行业数据,包括行业规模、增长趋势、平均薪资等,为求职者提供行业发展前景的参考。
  • 5、职业路径规划:根据求职者的长期职业目标和个人偏好,提供职业发展路径规划建议,包括必要的技能提升和转型建议。
  • 6、用户界面:设计直观易用的用户界面,使求职者能够轻松浏览职位、查看行业分析报告和获取职业建议。

1.4系统总体结构

数据采集层:

  • 通过爬取BOSS直聘和58同城等招聘网站收集薪资待遇,公司地点,公司福利等招聘信息
  • 通过爬取中国数据局各省份的不同行业随时间的占比变化
  • 将获取的招聘信息存储在云数据库中以便后续的匹配

前端:

  • 使用HTML、JavaScript进行界面设计,实现用户与系统的交互。用户可以输入自己的个人信息,查询匹配的职业以及获取AI给出的建议。

后端:

  • 使用Python语言和Flask框架实现,调用AI接口和爬虫数据存储处理信息并匹配,以及数据可视化。

二.个人分工

2.1爬取招聘网页

2.1.1主要代码块

    def parse(self, response):jobs = response.xpath("//ul[@class='job-list-box']/li")for job in jobs:b = 0t = ''item = JobItem()item['Occupation_Name'] = job.xpath(".//span[@class='job-name']//text()").extract_first()item['Location'] = job.xpath(".//span[@class='job-area']//text()").extract_first()item['Salary'] = job.xpath(".//span[@class='salary']//text()").extract_first()item['Work_Experience'] = job.xpath(".//ul[@class='tag-list']/li[1]//text()").extract_first()item['Education'] = job.xpath(".//ul[@class='tag-list']/li[2]//text()").extract_first()tags = job.xpath(".//div[@class='job-card-footer clearfix']//ul[@class='tag-list']//li")for tag in tags:if b==0:t = tag.xpath(".//text()").extract_first()b = b + 1else:t = t + '139842'+tag.xpath(".//text()").extract_first()item['Job_Keywords'] = tpart_url = job.xpath(".//a[@class='job-card-left']/@href").extract_first()detail_url =response.urljoin(part_url)yield scrapy.Request(url=detail_url,callback=self.parse_detail,meta={'item' : item})def parse_detail(self,response):a = 0w = ''t = ''item =response.meta['item']texts = response.xpath("//div[@class='job-detail-section']//div[@class='job-sec-text']//text()")for text in texts:t = t + text.extract()item['Details'] = twelfares = response.xpath(".//div[@class='job-tags']//span")for welfare in welfares:if a == 0:w = welfare.xpath(".//text()").extract_first()a = a + 1else:w = w + '139842' + welfare.xpath(".//text()").extract_first()item['Company_welfare'] = witem['Company_Name'] = response.xpath("//li[@class='company-name']//text()").extract()[1]part_url = response.xpath("//a[@class='look-all'][@ka='job-cominfo']/@href").extract_first()image_url = response.urljoin(part_url)yield scrapy.Request(url = image_url,callback=self.parse_image,meta={'item' : item})def parse_image(self,response):a = 0item = response.meta['item']img_url = ''t = ''images = -1if len(response.xpath("//ul[@class='swiper-wrapper swiper-wrapper-row']//li")) > 0:images = response.xpath("//ul[@class='swiper-wrapper swiper-wrapper-row']//li")if len(response.xpath("//ul[@class='swiper-wrapper swiper-wrapper-col']//li")) > 0:images = response.xpath("//ul[@class='swiper-wrapper swiper-wrapper-col']//li")texts = response.xpath("//div[@class='job-sec']//div[@class='text fold-text']//text()")for text in texts:t = t + text.extract()item['Company_Profile'] = tif images != -1:for image in images:if a ==0:img_url = image.xpath(".//img/@src").extract_first()a = a + 1else:img_url = img_url +'139842'+image.xpath(".//img/@src").extract_first()item['Company_Photo'] = img_urlyield item

item代码:

class JobItem(scrapy.Item):Occupation_Name = scrapy.Field()Location= scrapy.Field()Salary= scrapy.Field()Work_Experience= scrapy.Field()Education= scrapy.Field()Job_Keywords= scrapy.Field()Details= scrapy.Field()Company_Name= scrapy.Field()Company_Profile= scrapy.Field()Company_welfare= scrapy.Field()Company_Photo= scrapy.Field()

2.2获取全部职业接口

2.2.1导入并初始化FLask框架并设置CORS跨域(之后的接口有重复的就不写了)

  from flask_cors import CORSfrom flask import Flask, jsonifyimport randomimport pymysqlapp = Flask(__name__)CORS(app)

2.2.2数据库连接配置

  DB_CONFIG = {'host': '81.70.22.101','user': 'root','password': 'xxx','database': 'job','charset': 'utf8mb4'
}

2.2.3定义获取招聘数据的函数

def fetch_recruitment_data():"""从数据库中获取招聘数据"""connection = pymysql.connect(**DB_CONFIG)try:with connection.cursor(pymysql.cursors.DictCursor) as cursor:sql = "SELECT id, Occupation_Name, Location, Salary, Company_Name, big_kind FROM jobInfo"cursor.execute(sql)result = cursor.fetchall()finally:connection.close()return result

2.2.4定义省份招聘信息的接口

@app.route('/province-recruitment', methods=['GET'])
def get_province_recruitment():global initial_data# 判断是首次加载还是刷新if "loaded_once" not in get_province_recruitment.__dict__:get_province_recruitment.loaded_once = Trueresponse_data = initial_data  # 顺序固定else:response_data = random.sample(initial_data, len(initial_data))  # 顺序随机print("响应数据:", response_data)return jsonify({"code": 200,"message": "Success","data": response_data})

2.3获取职业详情的接口

2.3.1配置数据库连接

  DB_CONFIG = {"host": "81.70.22.101","user": "root","password": "xxx","database": "job","charset": "utf8mb4"
}
#### 2.3.2定义数据分割函数和从数据库获取招聘详情的函数
```pythondef split_data(data, delimiter="139842"):return data.split(delimiter) if data else []def get_recruitment_from_db(recruitment_id):connection = pymysql.connect(**DB_CONFIG)try:with connection.cursor() as cursor:sql = """SELECT Occupation_Name,Location,Salary,Work_Experience,Education,Job_Keywords,Details,Company_Name,Company_Profile,Company_Photo,Company_WelfareFROM jobInfoWHERE id = %s """cursor.execute(sql, (recruitment_id,))result = cursor.fetchone()if result:return {"Occupation_Name": result[0],"Location": result[1],"Salary": result[2],"Work_Experience": result[3],"Education": result[4],"Job_Keywords": split_data(result[5]),"Details": result[6],"Company_Name": result[7],"Company_Profile": result[8],"Company_Photo": split_data(result[9]),"Company_Welfare": split_data(result[10])}return Nonefinally:connection.close()

2.3.3定义接口:招聘详情查询

  @app.route('/recruitment-detail', methods=['GET'])
def get_recruitment_detail():recruitment_id = request.args.get('id')if not recruitment_id:return jsonify({"code": 400, "message": "recruitment_id is required"}), 400recruitment_detail = get_recruitment_from_db(recruitment_id)if recruitment_detail:return jsonify({"code": 200, "message": "Success", "data": recruitment_detail})else:return jsonify({"code": 404, "message": "Recruitment detail not found"}), 404

2.4 AI智能根据用户填写的简历给出建议的接口

2.4.1获取 Access Token

  def get_access_token():try:url = f"{AI_AUTH_URL}?grant_type=client_credentials&client_id={API_KEY}&client_secret={SECRET_KEY}"response = requests.post(url)response.raise_for_status()return response.json().get("access_token")except requests.RequestException as err:print(f"获取 Access Token 失败: {err}")return None

2.4.2调用 AI 模型生成结果

  def get_ai_response(payload, access_token):url = f"{AI_API_URL}?access_token={access_token}"headers = {"Content-Type": "application/json"}try:response = requests.post(url, json=payload, headers=headers)response.raise_for_status()return response.json()except requests.RequestException as err:print(f"AI API 请求失败: {err}")return {"error": "Failed to get response from AI API", "status_code": response.status_code}

2.4.3解析 AI 返回内容

  def parse_ai_response(response_text):sections = {"Current_Situation": "","Interview_Advice": "","Career_Direction": "","Communication_Skills": ""}pattern = r'====\s*(Current_Situation|Interview_Advice|Career_Direction|Communication_Skills)\s*====\n(.+?)(?=\n====|$)'matches = re.findall(pattern, response_text, re.DOTALL)for section_name, content in matches:sections[section_name.strip()] = content.strip()return sections

2.4.4 定义职业建议生成接口

  @app.route('/recommend-career-advice', methods=['POST'])
def recommend_career_advice():data = request.jsonrequired_params = ["desired_position", "expected_salary", "resume", "work_experience"]for param in required_params:if param not in data or not data[param]:return jsonify({"code": 400, "message": f"{param} is required"}), 400desired_position = data["desired_position"]expected_salary = data["expected_salary"]resume = data["resume"]work_experience = data["work_experience"]requirements = data.get("requirements", "")access_token = get_access_token()if not access_token:return jsonify({"code": 500, "message": "Failed to retrieve access token"}), 500sections = {"Current_Situation": "请详细描述应聘者的期望岗位的发展前景和就业情况。","Interview_Advice": "提供针对面试的详细建议,如如何准备面试,如何展示自己的优势等。","Career_Direction": "根据应聘者的期望职位和技能背景,提供详细的长期职业规划建议。","Communication_Skills": "提供应聘者在工作中的详细沟通技巧建议。"}results = {}for section, description in sections.items():ai_payload = {"messages": [{"role": "user","content": f"""
根据以下求职信息,生成详细的个性化职业规划建议。请确保按照以下部分返回回答,并在开头使用“==== {section} ====”分隔标识符,确保内容超过300字:
==== {section} ====
{description}期望职位: {desired_position}
期望薪资: {expected_salary}
工作经验: {work_experience}
简历: {resume}
求职要求: {requirements}确保返回的内容详细且字数不少于 300 字。
"""}],"temperature": 0.7,"max_tokens": 1024}response = get_ai_response(ai_payload, access_token)if "result" not in response:return jsonify({"code": 500, "message": f"Failed to generate {section}"}), 500results[section] = response["result"]parsed_results = parse_ai_response("\n".join(results.values()))if not parsed_results:return jsonify({"code": 500, "message": "Failed to parse AI response"}), 500return jsonify({"code": 200,"message": "Success","data": parsed_results})

三.心得体会

实战经验积累:

  • 通过实际参与项目,我深刻认识到实践的重要性。理论知识是解决问题的基础,但只有在实践中才能真正理解和灵活运用这些知识。无论是解决爬虫反制机制的问题,还是优化AI职业建议接口性能,每一次实践都让我在技术上更加自信,也积累了宝贵的经验。

技术能力跃升:

  • 项目的实施过程中,我深入应用了Scrapy爬虫框架、Flask后端框架以及MySQL数据库技术。这不仅帮助我加深了对这些工具的理解,还让我掌握了如何处理实际场景中的复杂问题,例如高效的数据采集与存储,以及接口性能优化。

协作的重要性:

  • 项目的成功离不开团队的共同努力。在任务分工和协作中,我感受到团队沟通的效率对于项目进度至关重要。通过频繁的讨论和反馈,我们在多个技术细节上找到了解决方案,这种团队协作的经历让我更加理解“众人拾柴火焰高”的意义。

项目推进与管理:

  • 从项目需求分析到实现功能,再到最终上线,我经历了完整的项目周期。这让我认识到,合理的规划和有效的管理是确保项目成功的关键。通过制定进度表、监控任务完成情况,以及合理分配资源,我积累了许多宝贵的项目管理经验。

问题处理与应对:

  • 在项目开发中,面对复杂的反爬策略、API调用限制以及数据解析等问题,我逐步锻炼了自己解决问题的能力。这些挑战不仅让我更加熟悉相关技术,也让我养成了冷静分析问题、快速学习新知识的习惯。

技术创新探索:

  • 此次项目中,我负责将大模型API集成到智能推荐系统中,实现了更精准、更个性化的职位建议服务。这让我深刻体会到技术创新的价值,敢于尝试新技术和新方法,不仅可以提升项目的用户体验,还能为项目带来更大的商业潜力。

持续学习成长:

  • 技术日新月异,只有保持学习的习惯,才能跟上时代的步伐。在这个项目中,我主动学习了多个新工具,并在团队中分享了自己的经验。我更加认识到,持续学习不仅能提升个人竞争力,也是推动团队进步的重要力量。

总的来说,这次项目让我在技术能力、问题解决、团队协作以及项目管理等多方面都得到了锻炼,同时也让我更清楚地意识到学习和实践结合的意义。

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

【bWAPP靶场】OS Command lnjection - Blind

命令盲注就是注入后没有返回信息,要根据反应时间判断命令是否成功执行 输入127.0.0.1输入 ||whoami `sleep 5 `

【bWAPP靶场】OS Command Injection

Level:low payload:www.nsa.gov;whoami原理:在DNS查询之后再执行dir命令 Level:medium 查看源码commandi_check_1是把&和;替换了,还可以使用| 构造payload:www.nsa.gov| whoamiLevel:high 查看源码escapeshellcmd()函数用来跳过字符串中的特殊符号,防止恶意用户通过…

【Windows安全】Windows文件关联深度解析:原理、应用与修复

在Windows操作系统中,文件关联是一项至关重要的功能,它决定了当用户双击一个文件时,哪个应用程序会被用来打开这个文件。文件关联机制通过将文件扩展名与特定的应用程序建立起一种依存关系,使得用户无需每次都手动选择打开文件的程序,从而提高了操作效率。本文将深入探讨W…

综合设计——多源异构数据采集与融合应用综合实践——个人总结

这个项目属于哪个课程 2024数据采集与融合技术实践组名、项目简介 组名:scrapy能帮我爬到美味蟹黄堡的秘方吗项目需求:文物不能很好的融入我们的生活,它们仿佛一具冰冷的尸体躺在博物馆的展示柜中,静静地接受着岁月的侵蚀和尘埃的覆盖。项目目标:赋予文物新的生命力,让它…

第 3 单元:微分:复合函数、隐函数和反函数 (链式法则、复合函数)

链式法则 常见的链式法则误解 例子: 例子: 识别复合函数 例子: 例子:利用链式法则求 cos(x) 的导数 例子:利用链式法则求 √(3x-x) 的导数 例子:利用链式法则求 ln(√x) 的导数 例子:

KubeWall:一款现代化的 Kubernetes 集群管理工具

以下文章来源于Github爱好者 ,作者KubeWall KubeWall 是一款功能强大的 Kubernetes 多集群管理工具,采用单一二进制文件的简便部署方式,为用户提供直观且易用的 Web 界面,用于高效管理和监控 Kubernetes 集群。为什么选择 KubeWall? KubeWall 致力于简化 Kubernetes 集群的…

【HW系列+技战法】网络监控告警及多角度资产安全加固技战法

一、技战法概述 随着公司的生产业务和网络不断增加建设,企业和组织面临着越来越多的设备、系统。关键节点设备是否采用冗余架构部署,是否存在设备单点故障风险,遭受网络攻击时是否可以及时进行响应等,它们是保障公司运行稳定性和连续性的重要课题。同时,我们还需要对关键设…

多源异构数据采集与融合应用综合实践

综合设计——多源异构数据采集与融合应用综合实践 Recomind荐宝这个作业属于哪个课程 首页 - 2024数据采集与融合技术实践 - 福州大学 - 班级博客 - 博客园组名、项目介绍 组名:超级无迪爬虫高手元始天尊暴龙战士 Recomind荐宝是一款创新型的购物推荐网站,它整合了多源异构数…

综合设计 ——多源异构数据采集与融合应用综合实践

这个作业属于哪个课程 https://edu.cnblogs.com/campus/fzu/2024DataCollectionandFusiontechnology/组名 超级无迪爬虫高手元始天尊暴龙战士项目介绍 Recomind荐宝是一款创新型的购物推荐网站,整合了多源异构数据与先进的大语言模型技术。无论用户是在寻找时尚服饰、电子产品…

数据采集综合实践

这个项目属于哪个课程 https://edu.cnblogs.com/campus/fzu/2024DataCollectionandFusiontechnology/组名、项目简介 组名:都给爷爬项目目标:为心理疾病患者进行个性化的音乐疗愈项目需求:市面上大多数音乐软件都需要会员而且存在打榜等现象,不能完全个性化推荐,我们希望我…

2024CSICN长城杯--Crypto--WriteUp

2024CSICN&长城杯--Crypto--WriteUprasnd task: from Crypto.Util.number import getPrime, bytes_to_long from random import randint import osFLAG = os.getenv("FLAG").encode() flag1 = FLAG[:15] flag2 = FLAG[15:]def crypto1():p = getPrime(1024)q = g…

OS笔记

os cpu执行两种性质的程序内核态程序(管态) 用户态程序内核态执行的特权指令包含:I/O指令 中断指令 存取内存中寄存器指令 程序状态字寄存器变更指令和硬件关联的指令(最底层)包含:时钟管理 中断处理 设备驱动运行比较频繁的指令(最底层的上层)包含:进程管理 内存管理 设…