102302134陈蔡裔数据采集第四次作业

news/2025/11/30 12:50:30/文章来源:https://www.cnblogs.com/ccy041130/p/19286113

第一题
核心代码和运行结果

from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.edge.options import Options
import time
import sqlite3# 配置浏览器
edge_options = Options()
edge_options.add_argument('--headless')
edge_options.add_argument('--disable-gpu')
driver = webdriver.Edge(options=edge_options)# 初始化数据库
def init_db():conn = sqlite3.connect('stock_market.db')conn.execute('''CREATE TABLE IF NOT EXISTS stocks (market_type TEXT,stock_code TEXT,stock_name TEXT,current_price REAL,change_rate REAL,change_amount REAL,volume INTEGER,turnover REAL,high_price REAL,low_price REAL,open_price REAL,prev_close REAL)''')conn.commit()conn.close()# 保存数据到数据库
def save_data(data):conn = sqlite3.connect('stock_market.db')conn.execute('''INSERT INTO stocks (market_type, stock_code, stock_name, current_price, change_rate, change_amount, volume, turnover, high_price, low_price, open_price, prev_close)VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)''', data)conn.commit()conn.close()# 显示数据库数据
def display_data():conn = sqlite3.connect('stock_market.db')cursor = conn.cursor()cursor.execute('SELECT * FROM stocks')rows = cursor.fetchall()print("\n股票市场数据:")print("市场\t代码\t名称\t现价\t涨跌幅%\t涨跌额\t成交量\t成交额\t最高\t最低\t开盘\t昨收")print("-" * 100)for row in rows:print(f"{row[0]}\t{row[1]}\t{row[2]}\t{row[3]}\t{row[4]}\t{row[5]}\t{row[6]}\t{row[7]}\t{row[8]}\t{row[9]}\t{row[10]}\t{row[11]}")conn.close()# 主爬虫函数
def crawl_stocks():markets = [('https://quote.eastmoney.com/center/gridlist.html#hs_a_board', '沪深A股'),('https://quote.eastmoney.com/center/gridlist.html#sh_a_board', '上证A股'), ('https://quote.eastmoney.com/center/gridlist.html#sz_a_board', '深证A股')]for url, market_name in markets:print(f"正在爬取{market_name}...")driver.get(url)time.sleep(4)# 获取股票行数据rows = driver.find_elements(By.CSS_SELECTOR, "table tbody tr")for row in rows[:25]:  # 每个市场取25条cells = row.find_elements(By.TAG_NAME, "td")if len(cells) > 10:stock_data = (market_name,cells[1].text,  # 股票代码cells[2].text,  # 股票名称cells[3].text,  # 最新价cells[4].text,  # 涨跌幅cells[5].text,  # 涨跌额cells[6].text,  # 成交量cells[7].text,  # 成交额cells[8].text,  # 最高cells[9].text,  # 最低cells[10].text, # 今开cells[11].text  # 昨收)save_data(stock_data)# 运行主程序
if __name__ == "__main__":init_db()crawl_stocks()driver.quit()display_data()print("\n数据爬取完成!")

image
image
image

image

作业心得
通过这次股票数据爬虫项目,我深刻体会到理论与实践的结合。在爬取东方财富网数据时,遇到了页面结构复杂、数据重复存储等问题,通过不断调试和优化代码,学会了如何更精准地定位元素和处理异常数据。特别是在处理数据库重复记录时,明白了数据清洗和去重的重要性。这次实践不仅提升了我的Python编程能力和Selenium自动化操作技巧,更培养了我解决实际问题的能力和耐心,认识到一个完整的数据采集系统需要考虑到数据质量、效率和稳定性等多个方面。
https://gitee.com/chen-caiyi041130/chen-caiyi/tree/master/作业4
第二题
核心代码和运行结果
模拟登录

# 模拟登录
#点击登录按钮
def click_login():login_xpaths = ["//button[contains(text(), '登录')]","//a[contains(text(), '登录')]","//*[contains(text(), '登录')]"]for xpath in login_xpaths:try:elements = driver.find_elements(By.XPATH, xpath)for element in elements:if element.is_displayed():element.click()print("点击登录按钮")return Trueexcept:continuereturn False
#在登录表中填写用户名和密码,处理iframe中的登录表单
def fill_login_form(username, password):iframes = driver.find_elements(By.TAG_NAME, "iframe")for iframe in iframes:try:driver.switch_to.frame(iframe)inputs = driver.find_elements(By.CSS_SELECTOR, "input")username_filled = Falsepassword_filled = Falsefor field in inputs:field_type = field.get_attribute('type') or ''placeholder = field.get_attribute('placeholder') or ''if not username_filled and field_type in ['text', 'tel'] and '手机' in placeholder:field.clear()field.send_keys(username)print("输入用户名")username_filled = Truecontinueif not password_filled and field_type == 'password' and '密码' in placeholder:field.clear()field.send_keys(password)print("输入密码")password_filled = Truecontinuedriver.switch_to.default_content()return username_filled and password_filledexcept:driver.switch_to.default_content()return False
#提交登录表单
def submit_login():iframes = driver.find_elements(By.TAG_NAME, "iframe")for iframe in iframes:try:driver.switch_to.frame(iframe)submit_selectors = ["button[type='submit']","input[type='submit']","button:contains('登')",".j-login-btn",".u-loginbtn"]for selector in submit_selectors:try:if "contains" in selector:for btn in driver.find_elements(By.XPATH, "//button[contains(text(), '登')]"):if btn.is_displayed():btn.click()print("提交登录")driver.switch_to.default_content()return Trueelse:submit_btn = driver.find_element(By.CSS_SELECTOR, selector)if submit_btn.is_displayed():submit_btn.click()print("提交登录")driver.switch_to.default_content()return Trueexcept:continuedriver.switch_to.default_content()except:driver.switch_to.default_content()return False
#检查登录是否成功
def check_login():time.sleep(3)user_selectors = [".user-info", ".user-name", "a[href*='user']"]for selector in user_selectors:try:element = driver.find_element(By.CSS_SELECTOR, selector)if element.is_displayed():print("登录成功")return Trueexcept:continuereturn False
#登录主函数
def login(username, password):print("开始登录...")driver.get("https://www.icourse163.org/")time.sleep(3)if not click_login():return Falsetime.sleep(3)if not fill_login_form(username, password):return Falseif not submit_login():return Falsereturn check_login()

爬取Ajax

#爬取Ajax
def get_course_info(url, course_id):driver.get(url)time.sleep(3)info = {"course_id": course_id, "course_name": f"课程{course_id}","university": "未知学校", "instructor": "未知教师","team_members": "未知教师", "student_count": "未知","schedule": "未知", "description": "暂无简介"}# 课程名称for selector in [".course-title", "h1", ".u-course-title"]:try:title = driver.find_element(By.CSS_SELECTOR, selector).text.strip()if title and len(title) > 2:info['course_name'] = titlebreakexcept:continue# 学校名称try:school = driver.find_element(By.XPATH, "//*[@id='j-teacher']/div/a/img").get_attribute('alt')if school:info['university'] = schoolexcept:for selector in [".u-course-org", ".school-name"]:try:school = driver.find_element(By.CSS_SELECTOR, selector).textif school:info['university'] = schoolbreakexcept:continue# 主讲教师teacher_selectors = [".f-fc3", ".teacher-name", ".instructor", "h3.f-fc3"]for selector in teacher_selectors:try:teacher_elems = driver.find_elements(By.CSS_SELECTOR, selector)for elem in teacher_elems:teacher = elem.text.strip()# 过滤掉"位授课老师"这样的文本,只保留真实姓名if (teacher and len(teacher) > 1 and '位授课老师' not in teacher and'课程团队' not in teacher andlen(teacher) < 10):  # 中文姓名通常2-4个字info['instructor'] = teacherbreakif info['instructor'] != "未知教师":breakexcept:continue# 团队成员team_members = []try:# 查找所有教师姓名元素name_elements = driver.find_elements(By.CSS_SELECTOR, ".f-fc3, .teacher-name, .t-name, .name")for elem in name_elements:name = elem.text.strip()if (name and len(name) > 1 and '位授课老师' not in name and'课程团队' not in name andlen(name) < 10 andname != info['instructor']):  # 排除主讲教师team_members.append(name)# 去重team_members = list(set(team_members))if team_members:info['team_members'] = ', '.join(team_members)else:info['team_members'] = info['instructor']  # 如果没有其他成员,使用主讲教师except Exception as e:print(f"抓取团队成员失败: {e}")info['team_members'] = info['instructor']# 参与人数try:count_text = driver.find_element(By.CSS_SELECTOR, "span.count").textmatch = re.search(r"\d+", count_text)if match:info['student_count'] = match.group()except:pass# 课程进度try:progress = driver.find_element(By.XPATH, "//*[@id='course-enroll-info']/div/div[1]/div[4]/span[@class='text']").textif progress:info['schedule'] = progressexcept:# 备用选择器for selector in [".course-schedule", ".progress", ".schedule"]:try:progress_elem = driver.find_element(By.CSS_SELECTOR, selector)if progress_elem.text:info['schedule'] = progress_elem.textbreakexcept:continue# 课程简介try:intro = driver.find_element(By.XPATH, "//*[@id='j-rectxt2']").textif intro:info['description'] = intro[:200] + "..." if len(intro) > 200 else introexcept:# 备用选择器for selector in [".course-description", ".intro", ".description", ".m-courseintro"]:try:intro_elem = driver.find_element(By.CSS_SELECTOR, selector)if intro_elem.text:intro_text = intro_elem.text.strip()info['description'] = intro_text[:200] + "..." if len(intro_text) > 200 else intro_textbreakexcept:continueprint(f"课程信息: {info['course_name']} | 学校: {info['university']} | 教师: {info['instructor']} | 参与人数: {info['student_count']}")print(f"团队成员: {info['team_members']}")print(f"课程进度: {info['schedule']}")print(f"课程简介: {info['description'][:50]}...")return info

数据库保存与查询

def save_course(conn, cursor, data):cursor.execute('''INSERT INTO course_info VALUES (NULL, %s, %s, %s, %s, %s, %s, %s, %s)''', (data['course_id'], data['course_name'], data['university'],data['instructor'], data['team_members'], data['student_count'],data['schedule'], data['description']))conn.commit()print(f"已保存: {data['course_name']}")def display_data(cursor):cursor.execute("SELECT * FROM course_info")records = cursor.fetchall()print("\n" + "="*150)print("MySQL课程信息:")print("="*150)print(f"{'ID':<3} {'课程号':<8} {'课程名称':<25} {'学校':<15} {'主讲教师':<12} {'团队成员':<15} {'参与人数':<10} {'进度':<20} {'简介':<30}")print("-"*150)for record in records:# 截断简介长度避免显示过长description = record[8][:30] + "..." if record[8] and len(record[8]) > 30 else record[8]print(f"{record[0]:<3} {record[1]:<8} {record[2]:<25} {record[3]:<15} {record[4]:<12} {record[5]:<15} {record[6]:<10} {record[7]:<20} {description:<30}")print(f"\n总计: {len(records)} 门课程")

主函数

if __name__ == "__main__":print("中国大学MOOC课程爬虫")conn, cursor = setup_database()cursor.execute("DELETE FROM course_info")conn.commit()if login("18065097076", "ccy20041130"):print("登录成功,开始爬取课程...")else:print("登录失败,爬取公开课程...")courses = ["https://www.icourse163.org/course/ZJU-1472847200","https://www.icourse163.org/course/ZJU-1003377027", "https://www.icourse163.org/course/ZJU-1472836187","https://www.icourse163.org/course/DUT-1463110162","https://www.icourse163.org/course/BIT-1001870001",]print(f"爬取 {len(courses)} 个课程...")for i, url in enumerate(courses, 1):print(f"处理第 {i} 个课程...")data = get_course_info(url, f"C{i:03d}")save_course(conn, cursor, data)time.sleep(2)display_data(cursor)driver.quit()cursor.close()conn.close()print("执行完成!")

image
image

作业心得
在完成这个中国大学MOOC课程爬虫项目的过程中,我深刻体会到了网络爬虫开发的挑战与乐趣。最初遇到了诸多困难:登录按钮无法定位、iframe处理复杂、表单填写失败等问题频发。通过不断调试,我发现网站使用了动态iframe加载登录表单,需要先切换到正确的iframe才能操作输入框。在数据爬取阶段,教师信息经常被错误地识别为"1位授课老师"这样的描述文本,通过添加过滤条件和备用选择器才解决了这个问题。数据库操作也遇到了表结构不匹配的报错,通过重新设计表结构得以解决。这个项目让我学会了如何处理复杂的网页结构、优化选择器策略、完善错误处理机制,最终成功实现了稳定登录和完整数据爬取的功能。
https://gitee.com/chen-caiyi041130/chen-caiyi/tree/master/作业4
第三题
开通MapReduce服务
image
Python脚本生成测试数据
image
配置Kafka
image
安装Flume客户端
image
image
配置Flume采集数据
image
image
作业心得
实验将课堂上学习到的Hadoop、Hive、Spark、Flink等理论知识与云上的具体操作相结合,解决了“纸上谈兵”的问题,遇到了真实环境中才会出现的配置、网络、性能问题,极大地提升了解决问题的能力。

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

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

相关文章

2025年国内防爆接地箱供应商推荐:接地箱定制靠谱企业有哪些

TOP1 推荐:无锡德刚精工机电设备有限公司 推荐指数:★★★★★ 口碑评分:国内防爆接地箱定制领域标杆企业 专业能力:无锡德刚精工机电设备有限公司深耕高压电力领域24年,是防爆接地箱定制的企业,拥有双研发中心及…

实用指南:攻防世界-cat_cat_new(任意文件读取、Linux敏感文件、flask-session伪造)

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

2025简历撰写网站TOP5权威推荐:资质齐全信誉好的简历平

就业竞争白热化背景下,一份专业简历成为职场人敲开理想岗位的金钥匙。2024年数据显示,超68%的HR会因简历排版混乱、内容空洞直接淘汰候选人,而使用专业简历平台制作的简历,面试邀约率可提升55%。但市场上简历工具鱼…

2025年浙江寄宿制美术高中服务哪家好?性价比之选与口碑排名

在艺术升学竞争白热化的当下,文化+专业双优成为美术生家长的核心诉求——既要专业画室的艺考资源,又要扎实的文化课保障,还要省心的寄宿制管理。面对浙江、上海、江苏三地琳琅满目的美术高中,如何避开专业强文化弱…

2025年十大杭州泡沫雕塑服务商厂家排行榜,精选泡沫雕塑厂家

为帮企业高效锁定适配自身需求的泡沫雕塑合作伙伴,避免选型走弯路,我们从工艺技术实力(如材质耐用性、造型还原度)、定制服务能力(含创意落地效率、场景适配性)、全周期服务质量(覆盖设计到安装维护)及真实客户…

`pytest + YAML + Allure` 的接口自动化测试框架是业界广泛运用的组合

pre { white-space: pre !important; word-wrap: normal !important; overflow-x: auto !important; display: block !important; font-family: "Consolas", "Monaco", "Courier New", …

2025年浙江美术高中口碑排行榜:3家能提供艺考指导的优质美

对于有志于艺术道路的初中生家庭而言,如何在纷繁复杂的美术高中中找到既专业又可靠的选择,是一个普遍的痛点。许多家长和学生往往在择校时面临信息不对称的问题,不清楚哪些学校能真正提供有效的艺考指导,也不知道如…

2025年口碑好的儿童保温杯/设计感保温杯实力厂家TOP推荐榜

2025年口碑好的儿童保温杯/设计感保温杯实力厂家TOP推荐榜 开篇:行业背景与市场趋势 随着消费者对健康生活方式的重视,保温杯市场持续增长,尤其是儿童保温杯和设计感保温杯的需求显著提升。据市场调研数据显示,2…

2025年十大泡沫雕塑厂家推荐,专业泡沫雕塑制造商全解析

在商业美陈、影视拍摄、婚礼堂装饰等场景中,泡沫雕塑凭借轻盈、可塑性强的特性成为创意落地的核心载体。但市场上泡沫雕塑制造商良莠不齐,如何找到靠谱的泡沫雕塑源头厂家?以下依据工艺实力、服务能力、口碑评价,为…

AI元人文构想:未来的算法规制——从“代码律法”到“价值共生”

AI元人文构想:未来的算法规制——从“代码律法”到“价值共生” 我们时代的权力结构正在经历一场深刻的数字化重构。算法的逻辑已不再局限于代码世界,而是系统地嵌入社会运行的基础层面——它重塑信息传播的路径,介…

2025年知名的大连学习3D建模高性价比课程榜

2025年知名的大连学习3D建模高性价比课程榜开篇:3D建模行业的发展与市场趋势随着数字经济的蓬勃发展,3D建模技术已成为影视动画、游戏开发、建筑设计、工业设计等多个领域的核心技能。据市场研究机构Statista数据显示…

2025年质量好的电袋复合除尘器高评价厂家推荐榜

2025年质量好的电袋复合除尘器高评价厂家推荐榜行业背景与市场趋势随着我国环保政策的日益严格和"双碳"目标的持续推进,工业除尘设备市场迎来了前所未有的发展机遇。电袋复合除尘器作为传统静电除尘器和布袋…

2025年比较好的打包箱高评价厂家推荐榜

2025年比较好的打包箱高评价厂家推荐榜 行业背景与市场趋势 近年来,随着建筑工业化、模块化的发展,打包箱式房屋因其快速搭建、环保节能、可重复利用等优势,在临时建筑、商业空间、文旅项目等领域得到广泛应用。特…

2025年比较好的加装电梯TOP品牌厂家排行榜

2025年比较好的加装电梯TOP品牌厂家排行榜行业背景与市场趋势随着中国城市化进程的不断推进和既有建筑改造需求的持续增长,加装电梯市场迎来了前所未有的发展机遇。据统计数据显示,2024年全国老旧小区加装电梯市场规…

2025年比较好的双层保温饭盒厂家实力及用户口碑排行榜

2025年双层保温饭盒厂家实力及用户口碑排行榜 行业背景与市场趋势 随着消费者对健康饮食和环保生活的重视,保温饭盒市场近年来持续增长。2025年,双层保温饭盒因其优异的保温和分层设计,成为职场人士、学生及户外…

2025年热门的日本留学签证/日本留学官方认可榜

2025年热门的日本留学签证/日本留学官方认可榜日本留学行业背景与市场趋势近年来,日本留学市场持续升温,根据日本学生支援机构(JASSO)数据显示,2023年在日本的外国留学生总数已突破30万人,其中中国留学生占比超过4…

2025年江浙沪老牌美术高中推荐:美术高中服务怎么联系?哪家

在艺术教育赛道日益细分的今天,选择一所兼具专业积淀与文化课保障的美术高中,成为无数艺术生家庭的关键决策。面对市场上良莠不齐的机构,如何避开重专业轻文化师资不稳定的坑?本文聚焦江浙沪地区,依据办学年限、升…

2025年度十大混凝土密封固化剂专业供应商排行榜,新测评精选

为帮地坪施工企业、工业厂房等客户高效锁定适配自身需求的混凝土密封固化剂合作伙伴,避免选型走弯路,我们从产品性能稳定性(如硬度提升率、耐磨度比)、技术支持能力(含施工工艺指导、定制化方案输出)、全周期服务…

2025年优秀的大连校企合作的公司实力机构名单

2025年优秀的大连校企合作的公司实力机构名单开篇:校企合作的市场趋势与行业背景近年来,随着产业升级和人才需求结构的变化,校企合作已成为连接教育与产业的重要桥梁。大连作为东北地区重要的经济中心和高等教育重镇…

2025年质量好的吨袋包装机厂家最新实力排行

2025年质量好的吨袋包装机厂家实力排行行业背景与市场趋势随着全球工业自动化水平的不断提升,吨袋包装机作为散装物料包装领域的关键设备,正经历着前所未有的技术革新与市场扩张。2025年,随着环保要求的日益严格和智…