数据采集第四次作业

Posted on 2024-11-12 16:23  六一!!  阅读(10)  评论(0编辑  收藏  举报

数据采集第四次作业

码云链接:数据采集第四次作业

作业①:使用 Selenium 和 MySQL 爬取东方财富网股票数据

作业要求

  • 熟练掌握

    • Selenium 查找 HTML 元素
    • 爬取 Ajax 网页数据
    • 等待 HTML 元素加载
  • 任务

    • 使用 Selenium 框架和 MySQL 数据库爬取“沪深A股”、“上证A股”、“深证A股”三个板块的股票数据。
    • 候选网站:东方财富网
  • 输出信息

    • 存储到 MySQL 数据库,字段命名如下(英文命名):

一、实验

1、实验思路

(1)环境搭建

  • 安装 Python 及必要的 Python 库。

  • 使用 webdriver-manager 自动管理 ChromeDriver,无需手动下载。

  • 配置 MySQL 数据库:安装并启动 MySQL 服务器。

(2)数据库设计

  • 创建数据库:liuyi4

  • 创建数据表并定义相应字段:

hs_a_stocks:存储沪深A股数据
sh_a_stocks:存储上证A股数据
sz_a_stocks:存储深证A股数据

  • 表结构(以 hs_a_stocks 为例):
点击查看代码
CREATE TABLE IF NOT EXISTS hs_a_stocks (
    id INT AUTO_INCREMENT PRIMARY KEY,
    bStockNo VARCHAR(20),
    bStockName VARCHAR(100),
    latestPrice DECIMAL(10, 2),
    changePercent DECIMAL(10, 2),
    changeAmount DECIMAL(10, 2),
    volume VARCHAR(50),
    amount VARCHAR(50),
    amplitude DECIMAL(10, 2),
    highest DECIMAL(10, 2),
    lowest DECIMAL(10, 2),
    opening DECIMAL(10, 2),
    lastClosing DECIMAL(10, 2)
);

(3)编写爬虫

  • 初始化数据库连接:

使用 pymysql 连接到 MySQL 数据库,并创建数据表。

  • 初始化 Selenium WebDriver:

使用 webdriver-manager 自动下载和管理 ChromeDriver。
配置 Chrome 浏览器为无头模式(headless),提高爬取效率。

  • 爬取数据:

访问东方财富网股票页面(沪深A股、上证A股、深证A股)。
使用显式等待(WebDriverWait)等待页面加载完成。
定位到股票数据表格,并提取表格中的数据。
将提取到的数据存储到列表中。

  • 数据存储:

使用 executemany 方法将数据批量插入到 MySQL 数据库中。
处理可能出现的异常,确保数据插入的可靠性。

  • 日志记录:

使用 logging 模块记录爬取过程中的关键步骤和错误信息。
日志文件命名为 stock_scraper.log。

  • 错误处理:

捕获并处理数据库连接错误、WebDriver 初始化错误、数据解析错误等。
在发生错误时,记录错误信息并终止程序。

2、核心代码

点击查看代码
# 初始化数据库连接
def init_db():
    try:
        conn = mysql.connector.connect(**db_config)
        cursor = conn.cursor()
        return conn, cursor
    except mysql.connector.Error as err:
        print(f"数据库连接错误: {err}")
        return None, None

# 初始化 Selenium WebDriver
def init_driver():
    chrome_options = Options()
    chrome_options.add_argument("--headless")  # 无头模式
    chrome_options.add_argument("--disable-gpu")
    chrome_options.add_argument("--window-size=1920,1080")
    chrome_options.add_argument("--no-sandbox")
    chrome_options.add_argument("--disable-dev-shm-usage")

    try:
        service = Service(ChromeDriverManager().install())
        driver = webdriver.Chrome(service=service, options=chrome_options)
        return driver
    except Exception as e:
        print(f"初始化 WebDriver 失败: {e}")
        return None

# 爬取单个板块的数据
def scrape_board(driver, url, cursor, table_name):
    try:
        driver.get(url)
        print(f"正在访问: {url}")

        # 等待表格加载完成
        WebDriverWait(driver, 60).until(
            EC.presence_of_element_located((By.ID, "table_wrapper-table"))
        )
        print("股票数据表格已加载。")

        # 获取所有的表格行
        rows = driver.find_elements(By.CSS_SELECTOR, "#table_wrapper-table tbody tr")
        print(f"找到 {len(rows)} 条数据。")

        stock_list = []
        for row in rows:
            columns = row.find_elements(By.TAG_NAME, "td")
            if len(columns) < 14:
                continue  # 跳过不完整的数据行

            try:
                stock_code = columns[1].text.strip()
                stock_name = columns[2].text.strip()
                latest_price = float(columns[4].text.strip())
                change_percent = float(columns[5].text.strip().replace('%', ''))
                change_amount = float(columns[6].text.strip())
                volume = columns[7].text.strip().replace(',', '')
                amount = columns[8].text.strip().replace(',', '')
                amplitude = float(columns[9].text.strip().replace('%', ''))
                highest = float(columns[10].text.strip())
                lowest = float(columns[11].text.strip())
                opening = float(columns[12].text.strip())
                last_closing = float(columns[13].text.strip())

                stock = (
                    stock_code, stock_name, latest_price, change_percent, change_amount,
                    volume, amount, amplitude, highest, lowest, opening, last_closing
                )
                stock_list.append(stock)
            except Exception as e:
                print(f"数据解析失败,跳过该行: {e}")
                continue

        if stock_list:
            insert_sql = f"""
                INSERT INTO {table_name} 
                (bStockNo, bStockName, latestPrice, changePercent, changeAmount, volume, amount, amplitude, highest, lowest, opening, lastClosing)
                VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s, %s)
            """
            cursor.executemany(insert_sql, stock_list)
            print(f"成功插入 {len(stock_list)} 条数据到 {table_name}。")
        else:
            print(f"未获取到任何数据,跳过插入到 {table_name}。")

    except Exception as e:
        print(f"爬取 {url} 时发生错误: {e}")

# 主函数
def main():
    # 网站链接
    urls = [
        "http://quote.eastmoney.com/center/gridlist.html#hs_a_board",  # 沪深A股
        "http://quote.eastmoney.com/center/gridlist.html#sh_a_board",  # 上证A股
        "http://quote.eastmoney.com/center/gridlist.html#sz_a_board"   # 深证A股
    ]

    # 表格名称
    table_names = ['hs_a_stocks', 'sh_a_stocks', 'sz_a_stocks']

    # 初始化数据库和浏览器
    conn, cursor = init_db()
    if not conn:
        return

    driver = init_driver()
    if not driver:
        conn.close()
        return

    try:
        for url, table_name in zip(urls, table_names):
            scrape_board(driver, url, cursor, table_name)
            time.sleep(5)  # 等待一段时间,避免请求过于频繁
    except Exception as e:
        print(f"爬虫过程中发生严重错误: {e}")
    finally:
        # 关闭数据库连接
        cursor.close()
        conn.close()
        print("数据库连接已关闭。")

        # 关闭浏览器
        driver.quit()
        print("WebDriver 已关闭。")

        print("数据抓取并存储完成!")

if __name__ == "__main__":
    main()
  • 数据库连接:连接到 MySQL 数据库,并准备好数据插入操作。
  • 浏览器控制:使用 Selenium 控制 Chrome 浏览器打开目标网页,并等待页面元素加载完成。
  • 数据提取与存储:提取网页中的股票数据,并将其存储到 MySQL 数据库中。
  • 错误处理与日志记录:处理可能出现的异常,并记录爬取过程中的关键步骤和错误信息。

3、输出结果

终端输出结果如下:

mysql的表格如下:

二、实验心得

通过本次实验,我掌握了使用 Selenium 和 MySQL 爬取股票数据的基本方法。实验过程中,遇到了数据解析、数据库连接等问题,通过查阅资料和调试,最终成功解决了这些问题。实验结果表明,爬虫脚本能够稳定运行,数据存储格式合理,达到了预期的实验目标。

作业②:使用 Selenium 和 MySQL 爬取中国大学MOOC课程信息

作业要求

  • 熟练掌握

    • Selenium 查找 HTML 元素
    • 用户模拟登录
    • 爬取 Ajax 网页数据
    • 等待 HTML 元素加载
  • 任务

    • 使用 Selenium 框架和 MySQL 数据库爬取中国大学MOOC网站的课程资源信息。
    • 课程信息包括:课程号、课程名称、学校名称、主讲教师、团队成员、参加人数、课程进度、课程简介。
    • 候选网站:中国大学MOOC
  • 输出信息

    • 存储到 MySQL 数据库,字段命名如下(英文命名):

      Id cCourse cCollege cTeacher cTeam cCount cProcess cBrief
      1 Python数据分析与展示 北京理工大学 嵩天 嵩天 470 2020年11月17日 ~ 2020年12月29日 “我们正步入一个数据或许比软件更重要的新时代。——Tim O'Reilly” ……
  • Gitee 文件夹链接


一、实验

1、实验思路

(1)环境搭建

  • 安装 Python 及必要的 Python 库。

  • 安装 MySQL:

  • 下载浏览器驱动:使用 webdriver-manager 自动管理 ChromeDriver,无需手动下载。

(2)数据库设计

创建一个名为 mooc 的数据库,并在其中创建一个表 courses 来存储课程信息。

(3)编写爬虫

进入开发者模式,确保登录框的定位和元素选择器正确。

检查登录框按钮定位。

检查登录框中手机号输入框定位。

数据库操作:

  • 使用 SQLite 数据库存储爬取到的课程信息。
  • 设计数据库表结构,包括课程号、课程名称、学校名称、主讲教师、团队成员、参加人数、课程进度和课程简介等字段。

模拟登录:

  • 模拟用户输入用户名(手机号)和密码,点击登录按钮。
  • 处理登录框的 iframe 切换。

爬取课程信息:

  • 访问课程列表页面。
  • 遍历课程卡片,提取课程信息。
  • 处理分页,爬取多页课程信息。

数据存储:

  • 将爬取到的课程信息插入 SQLite 数据库。
  • 将数据库中的数据导出为 CSV 文件。

异常处理和日志记录:

  • 使用 try-except 块捕获并处理异常。
  • 打印日志信息以便调试。

2、核心代码

点击查看代码
```plaintext
options = webdriver.ChromeOptions()
options.add_experimental_option('prefs', {'profile.managed_default_content_settings.images': 2})
browser = webdriver.Chrome(options=options)
url = "https://www.icourse163.org/search.htm?search=数据库#/"


class moocDB:
    def __init__(self):
        self.con = mysql.connector.connect(
            host="localhost",
            user="liuying",
            password="wjk5489464",
            database="mooc_data"
        )
        self.cursor = self.con.cursor()

    def closeDB(self):
        self.con.commit()
        self.con.close()

    def insert(self, cCourse, cCollege, cTeacher, cTeam, cCount, cProcess, cBrief):
        print(
            f"Inserting record: Name={cCourse}, School={cCollege}, Teacher={cTeacher}, Team={cTeam}, Person={cCount}, Jindu={cProcess}, Jianjie={cBrief}")
        self.cursor.execute(
            "INSERT INTO Courses (cCourse, cCollege, cTeacher, cTeam, cCount, cProcess, cBrief) VALUES (%s, %s, %s, %s, %s, %s, %s)",
            (cCourse, cCollege, cTeacher, cTeam, cCount, cProcess, cBrief))


def login():
    login_button = browser.find_element(By.XPATH, '//a[@class="f-f0 navLoginBtn"]')
    login_button.click()
    frame = browser.find_element(By.XPATH, '//div[@class="ux-login-set-container"]/iframe')
    browser.switch_to.frame(frame)
    inputUserName = browser.find_element(By.XPATH, '//div[@class="u-input box"][1]/input')
    inputUserName.send_keys("19190948081")
    inputPasswd = browser.find_element(By.XPATH, '//div[@class="inputbox"]/div[2]/input[2]')
    inputPasswd.send_keys("Lzt270823")
    login_button = browser.find_element(By.XPATH, '//*[@id="submitBtn"]')
    login_button.click()
    time.sleep(5)


def next_page():
    next_button = browser.find_element(By.XPATH, '//li[@class="ux-pager_btn ux-pager_btn__next"]/a')
    next_button.click()


def start_spider(moocdb):
    browser.get(url)
    count = 0
    for i in range(2):
        WebDriverWait(browser, 1000).until(EC.presence_of_all_elements_located((By.ID, "j-courseCardListBox")))
        time.sleep(random.randint(3, 6))
        browser.execute_script('document.documentElement.scrollTop=0')

        for link in browser.find_elements(By.XPATH, '//div[@class="u-clist f-bgw f-cb f-pr j-href ga-click"]'):
            count += 1
            try:
                name = link.find_element(By.XPATH, './/span[@class=" u-course-name f-thide"]').text
            except:
                name = 'none'
            try:
                school = link.find_element(By.XPATH, './/a[@class="t21 f-fc9"]').text
            except:
                school = 'none'
            try:
                teacher = link.find_element(By.XPATH, './/a[@class="f-fc9"]').text
            except:
                teacher = 'none'
            try:
                team = link.find_element(By.XPATH, './/span[@class="f-fc9"]').text
            except:
                team = 'none'
            try:
                person = link.find_element(By.XPATH, './/span[@class="hot"]').text
                if person:
                    person = int(''.join(filter(str.isdigit, person)))  # 提取数字并转换为整数
                else:
                    person = 0
            except:
                person = 0
            try:
                jindu = link.find_element(By.XPATH, './/span[@class="txt"]').text
            except:
                jindu = 'none'
            try:
                jianjie = link.find_element(By.XPATH, './/span[@class="p5 brief f-ib f-f0 f-cb"]').text
            except:
                jianjie = 'none'

            moocdb.insert(name, school, teacher, team, person, jindu, jianjie)

        next_page()
    login()


def main():
    moocdb = moocDB()
    start_spider(moocdb)
    moocdb.closeDB()


if __name__ == '__main__':
    main()
    browser.quit()

(1)模拟用户登录

  • 定位登录按钮:使用 XPath 定位登录按钮,并点击。
  • 处理登录框:等待登录框出现,并切换到登录框的 iframe。
  • 输入用户名和密码。
  • 点击登录按钮。
  • 等待登录完成:使用 time.sleep(5) 等待登录完成。

(2)爬取课程信息

  • 访问课程列表页面:打开目标网址(搜索“数据库”相关课程)。
  • 等待课程列表加载:使用 WebDriverWait 等待课程列表加载完成。
  • 遍历课程卡片:遍历所有课程卡片,提取课程名称、学校名称、主讲教师、团队成员、参加人数、课程进度和课程简介等信息。
  • 使用 try-except 块处理可能缺失的元素。
  • 插入数据到数据库:将爬取到的课程信息插入到 MySQL 数据库中。
  • 处理分页:点击“下一页”按钮,爬取多页课程信息。

3、输出结果

浏览器成功实现用户模拟登录

在终端运行结果如下:

mysql存储数据如下:

二、实验心得

通过本次实验,我深入了解了如何使用 Selenium 自动化技术进行网页爬取,并掌握了将爬取到的数据存储到 MySQL 数据库中的方法。在实际应用中,自动化爬虫可以大大提高数据采集的效率,但也需要注意反爬机制的应对和数据存储的安全性。未来,我将继续优化爬虫代码,提高其稳定性和效率,并探索更多数据分析和处理的方法。

  • 自动化爬虫的优势
    效率高:相比手动操作,自动化爬虫可以快速地爬取大量数据,节省时间和人力。
    稳定性强:通过使用 WebDriverWait 和异常处理,爬虫可以更稳定地运行,减少因页面加载过慢或元素缺失导致的错误。

  • 数据存储的重要性
    结构化存储:将爬取到的数据存储到数据库中,可以方便地进行后续的数据分析和处理。
    数据完整性:使用参数化查询插入数据,可以有效防止 SQL 注入,保证数据的完整性和安全性。

  • 反爬机制的应对
    延时与随机性:通过 time.sleep() 和 random.randint() 控制爬虫的延时和随机性,可以有效减少被网站识别为爬虫的风险。
    浏览器指纹:使用 Chrome 浏览器进行爬取,可以模拟真实用户行为,减少被网站检测到的概率。

作业③:华为云大数据实时分析处理实验

作业要求

  • 掌握
    • 大数据相关服务
    • Xshell 的使用

输出:实验关键步骤或结果截图。

一、实验步骤及过程

环境搭建

  • 任务一:开通 MapReduce 服务。

1、创建集群

2、弹性公网IP绑定:

3、添加安全组规则:

实时分析开发实战

  • 任务一:使用 Python 脚本生成测试数据。

1、登录MRS的master节点服务器

2、使用more命令查看生成的数据

  • 任务二:下载安装并配置 Kafka。

1、进入MRS Manager集群管理

2、登录MRS集群管理界面

3、下载Kafka客户端

4、校验下载的客户端文件包

解压与校验:

界面显示如上信息,表明文件包校验成功。

5、安装Kafka运行环境并查看解压后文件。

显示安装成功。

6、执行命令配置环境变量。

7、安装Kafka到目录“/opt/KafkaClient”

系统显示以上结果表示客户端运行环境安装成功。

8、在kafka中创建topic并查看topic信息

查看topic信息

  • 任务三:安装 Flume 客户端。

1、下载客户端

2、文件包检验成功

3、安装客户端运行环境

4、执行命令配置环境变量。

5、安装Flume客户端

6、重启Flume服务

  • 任务四:配置 Flume 采集数据。

1、修改配置文件

2、创建消费者消费kafka中的数据

3、在新窗口进入Python脚本所在目录,执行python脚本,再生成一份数据

4、查看原窗口,可以看到已经消费出了数据:

有数据产生,表明Flume到Kafka目前是打通的。

5、测试完毕,在新打开的窗口输入exit关闭窗口,在原窗口输入 Ctrl+c退出进程。

二、实验心得

在本次实验中,通过搭建大数据实时分析环境,我完成了包括开通MapReduce服务、生成测试数据、配置Kafka、安装Flume客户端以及配置Flume数据采集等一系列任务。在开通MapReduce服务的过程中,我学习了如何配置集群、绑定弹性公网IP及设置安全组规则,为实时数据处理环境的搭建奠定了基础。随后,通过编写Python脚本生成模拟的双十一电商销售数据,真实模拟了高峰期的交易流入,为Kafka的配置、数据传输和分析提供了有效的测试数据。这一过程让我深入理解了数据源的生成与数据流动的基本原理。在配置Kafka和安装Flume客户端时,我进一步掌握了消息队列和数据采集的技术流程,成功实现了数据从Flume到Kafka的稳定传输,构建了可靠的实时数据流管道。最后,通过修改Flume的配置文件,定义了数据流动路径,并将数据成功导入到MySQL数据库中,完整地体验了从数据源、消息传输到数据存储的实时数据处理闭环。这次实验不仅让我对大数据实时分析流程有了更清晰的理解,还提升了我在实际应用中使用MapReduce、Kafka和Flume等多种工具进行实时数据处理的能力,为今后进行大规模数据分析和实时数据处理积累了宝贵的实践经验。

Copyright © 2024 六一!!
Powered by .NET 9.0 on Kubernetes