数据采集与融合技术实践4

数据采集与融合技术实践4

任务一

任务要求

使用Selenium框架+ MySQL数据库存储技术路线爬取“沪深A股”、“上证A股”、“深证A股”3个板块的股票数据信息。
候选网站:东方财富网:http://quote.eastmoney.com/center/gridlist.html#hs_a_board

实验思路

我采用 Selenium 爬取东方财富网的“沪深A股、上证A股、深证A股”三个板块数据,并使用 MySQL 进行存储。程序通过 ChromeDriver 打开网页,利用隐式等待与 WebDriverWait 显式等待确保 Ajax 加载的股票表格完全显示。随后用 CSS 选择器定位 <table><tbody><tr>,逐行提取股票代码、名称、最新价、涨跌幅等字段,并对带逗号、百分号的数值做格式清洗。最终,使用 pymysql 将数据按英文表头批量插入数据库,实现从网页动态数据获取到结构化存储的完整流程。

flowchart LR B([初始化环境Selenium + MySQL]) B --> C{遍历板块沪深A / 上证A / 深证A} C --> D[打开板块页面等待并解析表格数据] D --> E[清洗、转换数据并写入 t_stock] E --> H{还有未处理的行?} H -->|是| E H -->|否| I{还有未处理的板块?} I -->|是| C I -->|否| J([关闭浏览器关闭数据库连接]) %% 样式定义 classDef process fill:#E9F0FF,stroke:#4C6FFF,color:#1A2753; classDef decision fill:#FFE9B3,stroke:#D79B00,color:#5A3B00; %% 应用样式 class B,D,E,J process; class C,H,I decision;

代码和图片

首先,在sql中创建好数据表,随后编写程序,通过 Selenium 启动 Chrome 浏览器并设置隐式等待

    #建立与数据库的链接
    conn = pymysql.connect(
        host="127.0.0.1",
        port=3306,
        user="root",
        password="07734",
        database="stockdb",
        charset="utf8mb4"
    )
    #选择好driver
    options = webdriver.ChromeOptions()
    options.add_argument("--start-maximized")
    driver = webdriver.Chrome(options=options)
    driver.implicitly_wait(10)
    #设置隐式等待
    wait = WebDriverWait(driver, 20)
    time.sleep(2)

    rows = wait.until(
        EC.presence_of_all_elements_located(
            (By.CSS_SELECTOR, "table tbody tr")
        )
    )

一开始,进入网页时,会有一个弹窗,不过测试以后发现并不影响
image

通过观察可以发现,我们要的数据保存在table下的tbody中的tr块之中
image
所以我使用css选择器,找到所有<table><tbody><tr>下的数据做成列表,并逐一取出

    rows = wait.until(
        EC.presence_of_all_elements_located(
            (By.CSS_SELECTOR, "table tbody tr")#选出所有\<table\>\<tbody\>\<tr\>下的数据
        )
    )
        for row in rows:
            tds = row.find_elements(By.TAG_NAME, "td")
            if len(tds) < 14:
                continue
            stock_no = tds[1].text.strip()#序号
            stock_name = tds[2].text.strip()#名字,同时3里面的数据不是我们要的,所有就不取了
            def to_float(x: str):
                x = x.replace(',', '').replace('%', '').strip()
                return float(x) if x not in ("", "--") else None
            latest = to_float(tds[4].text)#最新价
            change_pct= to_float(tds[5].text)#涨跌幅
            change_amt = to_float(tds[6].text)#涨跌额
            volume = tds[7].text.strip()#成交量
            turnover = tds[8].text.strip()#成交额
            amplitude= to_float(tds[9].text)#振幅
            high_price = to_float(tds[10].text)#最高
            low_price = to_float(tds[11].text)#最低
            open_price = to_float(tds[12].text)#今开
            pre_close= to_float(tds[13].text)#昨收

最后,将这些数据存到数据库里建好的表之中

    sql = """
        INSERT INTO t_stock
        (board, bStockNo, bStockName, latestPrice,
         changePct, changeAmt, volume, turnover,
         amplitude, highPrice, lowPrice, openPrice, preClose)
        VALUES
        (%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s)"""#用来后续存数据的语句


        data = (
            board_code,
            stock_no, stock_name, latest,
            change_pct, change_amt, volume, turnover,
            amplitude, high_price, low_price, open_price, pre_close
        )#这里的这些数据已经在前文中被取好

        cur.execute(sql, data)#执行语句

接下来,运行程序,并在sql中查看结果,这里就先展示十条。
mysql:
2707f600aba82d172c999414bcc9c9a7

实验心得

通过这次实验,我对 Selenium 自动化爬虫和 MySQL 数据库存储有了真正的实践认识。之前只知道网页数据能被爬取,但动手做之后才发现动态加载、元素等待、数据清洗这些步骤都非常关键。像东方财富这种 Ajax 页面,表格内容不是马上出现的,一开始总是抓不到 行,后来通过 WebDriverWait 配合显式等待才成功解决。爬取过程中也遇到过 HTML 行列不齐、 不够导致越界的问题,我通过判断列数跳过异常行,保证数据准确。另外,许多数字带逗号、百分号或显示为“--”,无法直接转成 float,我就写了 to_float() 来统一清洗数据。数据库部分也因为字段类型不匹配报过错,检查表结构并改成合适的类型后才正常插入。

任务二

任务要求

熟练掌握 Selenium 查找HTML元素、实现用户模拟登录、爬取Ajax网页数据、等待HTML元素等内容。
使用Selenium框架+MySQL爬取中国mooc网课程资源信息(课程号、课程名称、学校名称、主讲教师、团队成员、参加人数、课程进度、课程简介)
候选网站:中国mooc网:https://www.icourse163.org
输出信息:MYSQL数据库存储和输出格式

实验思路

首先便是我认为这个实验里面最难的部分————登录机制。首先,该网站的登录表单是嵌在一个动态加载的 iframe 里,必须先切换到 iframe 才能找到手机号和密码输入框,否则 Selenium 一直定位不到元素。同时,登录页面整体是 Ajax 异步加载的,元素不是一次性渲染出来的,如果不配合显式等待,很容易出现“找不到元素”或元素尚未可点击的异常。如果选择手动登录再自动爬取的话,那这些就都不用考虑了,但是这样会使得爬取还需要手动操作,总感觉少点味。所以我最后还是决定尝试用代码自动爬取。
登录部分的流程大致是这样:程序先通过 Selenium 启动 Chrome 浏览器,打开慕课的登录页面,简单等待几秒。接着,登录表单其实是嵌在一个 iframe 里的,所以我先用 WebDriverWait 等待 iframe 加载好,并切换到这个 iframe 中,再在里面用 ID 和 CSS 选择器分别定位到手机号输入框(id="phoneipt")和密码输入框。找到输入框之后,先清空原有内容,再依次输入手机号和密码,然后在密码框中发送回车键提交表单。最后程序等待几秒,让服务器完成验证,并切回到主页面,同时打印当前页面标题和 URL,用来确认登录是否成功。
后面的步骤就比较经典了,登录成功后,构造包含关键词(如“大数据”)的搜索 URL(因为主页面的课程信息比较凌乱,不好爬取,所以选择搜索一个关进啊词来爬取),进入搜索结果页,等待异步加载完成,再按课程卡片的外层 div 依次找到每一门课程。对每个课程卡片,通过 CSS 选择器提取课程名称、学校名称、主讲教师、教师团队、参加人数、课程进度和课程简介等字段,把它们存下来。最后使用 pymysql 连接本地 MySQL,将这些课程信息批量插入到事先建好的 mooc_course 表中,本实验就完成了。

graph LR A([开始]) --> B[启动浏览器] B --> C[自动登录 MOOC] C --> D[打开搜索页(关键词“大数据”)] D --> E[等待课程卡片加载] E --> F[解析课程信息列表] F --> G[批量写入 MySQL] G --> H([结束]) %% 样式定义 classDef startEnd fill:#4C6FFF,stroke:#2740FF,color:#ffffff,stroke-width:2px; classDef step fill:#E0F2FF,stroke:#4C6FFF,color:#111827,stroke-width:1px; classDef highlight fill:#FDE68A,stroke:#F59E0B,color:#78350F,stroke-width:1px; %% 节点应用样式 class A,H startEnd; class B,D,E,F,G step; class C highlight;

代码和图片

首先是登录界面
image
红框的部分就是密码区域,可以看到页面同时存在两个 input type="password":上面那个带有 style="display: none",是隐藏的假输入框,真正可输入密码的是下面那个带 class="j-inputtext dlemail" 的元素,所以在 Selenium 中必须用 input.j-inputtext.dlemail[type='password'] 这样的 CSS 选择器去定位。不然就会掉到假输入框的坑里。
相关代码:

    name_input = wait.until(
        EC.element_to_be_clickable((By.ID, "phoneipt"))
    )
    pass_input = wait.until(
        EC.element_to_be_clickable(
            (By.CSS_SELECTOR, "input.j-inputtext.dlemail[type='password']")
        )
    )

找到以后,就输入密码,并且发送回车提交

    name_input.clear()
    name_input.send_keys(phone)
    time.sleep(0.3)

    pass_input.clear()
    pass_input.send_keys(password)
    time.sleep(0.3)

    pass_input.send_keys(Keys.RETURN)

这样才能登录上去。
登录以后就好办了,先把关键词(我这里用的是“大数据”)用 quote 做 URL 编码,拼成搜索地址并用 Selenium 打开搜索结果页。由于课程列表是 Ajax 异步加载的,所以先用 WebDriverWait 等待页面中出现若干个 div._3NYsM 这种课程卡片外层元素,再稍微 sleep 一下保证内容渲染完成。接着通过 find_elements 拿到所有课程卡片,在卡片内部用 CSS 选择器依次提取课程名称、学校名称、主讲教师、教师团队、课程简介、课程进度等字段,对“xxx人参加”这一栏用正则把人数的数字提出来。后面存入数据库。
这是我们要的数据保存的地方,可以发现由于网页显示字体里面,有些颜色不一样(比如“大数据”三个字),导致一段字被存在了不同的span块中,不过我用safe_text(By.CSS_SELECTOR, "div.m7l9I div._1vfZ-")这样的语句能直接提取并拼接出来。
image
这里是课程进度和参加人数,可以用同样的方式爬取下来。
image

相关代码:

    encoded_kw = quote(keyword)
    search_url = f"https://www.icourse163.org/search.htm?search={encoded_kw}#/"
    driver.get(search_url)
    #等课程卡片加载出来
    WebDriverWait(driver, 15).until(
        lambda d: len(d.find_elements(By.CSS_SELECTOR, "div._3NYsM")) > 0
    )
    time.sleep(2)#再等一会儿,防止内容没渲染完
    cards = driver.find_elements(By.CSS_SELECTOR, "div._3NYsM")
    print("找到课程数量:", len(cards))
    data_list = []
    seen = set() #这个是去重用的
    for card in cards:
        if len(data_list) >= max_num:
            break
        info = parse_course_card(card)
        name = info["cCourse"]
        college = info["cCollege"]
        if not name:
            continue
        key = (name, college)
        if key in seen:
            continue
        seen.add(key)
        data_list.append(info)

后面把拿到的data_list存到数据库就行

结果展示

自动登录的过程录像录像

过程全自动,包括登录部分,这里我用的是我自己的账号,我将账号和密码写在代码里,当出现登录窗口后便会自动输入,具体效果如下面的动图中所示
屏幕录制 2025-12-05 224710

sql数据

image
这里由于课程简介很长,所以就不全展示出来,而选择只展示前25个字符。

实验心得

这次的实验中,自动登录这一步让我卡了很久,最后我通过查阅博客园,csdn等网站,我才明白了有的网站会有多个输入框,而真正有效果的输入框只有一个。我的问题就是每次都会把账号密码输入到虚假的输入框里,在检查了网页结构后,我成功解决了这个问题,这次的实验让我受益匪浅。

任务三

任务要求

掌握大数据相关服务,熟悉Xshell的使用
完成文档 华为云_大数据实时分析处理实验手册-Flume日志采集实验(部分)v2.docx 中的任务,即为下面5个任务,具体操作见文档。
环境搭建:
任务一:开通MapReduce服务
实时分析开发实战:
任务一:Python脚本生成测试数据
任务二:配置Kafka
任务三: 安装Flume客户端
任务四:配置Flume采集数据

实验思路

首先,在云平台上购买并开通弹性公网IP、MapReduce服务、云数据库 RDS、数据湖探索等大数据相关服务,同时完成跨源激活,为后续组件之间的数据打通做好准备;随后开通数据可视化DLV 服务,用于后面的结果展示。环境就绪后,使用PuTTY远程登录到集群的master节点,进入/opt/client/目录,通过vi编写并运行Python脚本,用于自动生成一批测试数据。接着配置并安装 Kafka与Flume客户端:先解压安装包、完成客户端安装,再编写 Flume 配置,让 Flume 作为采集端把生成的测试数据采集并发送到Kafka中。最后创建Kafka消费者,实时消费并查看 Kafka 中的数据,同时再运行一次Python脚本生成新数据,验证从“数据生成 → Flume 采集 → Kafka 消费”的整条链路是通的

代码与图片

首先,购买弹性公网ip,MapReduce服务,云数据库服务RDS,数据湖探索服务等产品,同时进行跨源激活。
image
接着,开通数据可视化服务
进入DLV控制台,可以看到已开通完成
image

接着启动putty,准备开始实验
Python脚本生成测试数据,首先,登录master节点
image
进入/opt/client/目录,使用vi命令编写Python脚本
image

执行脚本,并查看生成数据
image

接着,配置Kafka,并安装Flume客户端
解压压缩包获取校验文件与客户端配置包
image

客户端安装成功界面:
image

接着配置Flume采集数据,创建消费者消费kafka中的数据,新开一个窗口,进入Python脚本所在目录,执行python脚本,再生成一份数据。返回原窗口,查看。
image

实验心得

一开始在控制台里开通弹性公网IP、MapReduce、RDS、数据湖探索、DLV等一堆云服务,其实挺懵的,但一步步把环境搭起来之后,再用PuTTY登录master节点、自己写Python脚本造测试数据,就能明显感受到“数据是怎么从产生到流动”的。后面配置Kafka和Flume时一开始总是连不通、消费不到数据,只能对着日志一点点排查,后面发现是kafka的路径不对。最后看到消费者窗口里成功打印出自己刚生成的那批数据,还是挺有成就感的。这次实验让我更直观地理解了数据采集、消息队列、实时消费这些概念。

github链接

https://gitee.com/hhz07734/parse/tree/master/practice_4

posted @ 2025-12-09 23:28  正三???  阅读(3)  评论(0)    收藏  举报