2023数据采集与融合技术实践作业四

发布时间 2023-11-03 23:37:43作者: 失重漂流

第四次作业

一、作业内容

  • 作业:

  • 要求:

    • 熟练掌握 Selenium 查找HTML元素、爬取Ajax网页数据、等待HTML元素等内容。
    • 使用Selenium框架+ MySQL数据库存储技术路线爬取“沪深A股”、“上证A股”、“深证A股”3个板块的股票数据信息。
  • 候选网站:东方财富网:http://quote.eastmoney.com/center/gridlist.html#hs_a_board

  • 输出信息:MYSQL数据库存储和输出格式如下,表头应是英文命名例如:序号id,股票代码:bStockNo……,由同学们自行定义设计表头:

  • Gitee文件夹链接
    Git文件夹

序号 股票代码 股票名称 最新报价 涨跌幅 涨跌额 成交量 成交额 振幅 最高 最低 今开 昨收
1 688093 N世华 28.47 62.22% 10.92 26.13万 7.6亿 22.34 32.0 28.08 30.2 17.55
2......
  • 代码:
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.common.by import By
from selenium.webdriver.common.action_chains import ActionChains
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC  
import time
import openpyxl
import sqlite3

conn = sqlite3.connect('深证A股.db')  #上证A股.db 沪深京A股.db 深证A股.db
cursor = conn.cursor()
# 创建一个表来存储股票信息
cursor.execute('''CREATE TABLE IF NOT EXISTS stocks
                (id INTEGER PRIMARY KEY,
                code TEXT,
                name TEXT,
                latest_price TEXT,
                change_percent TEXT,
                change_amount TEXT,
                volume TEXT,
                turnover TEXT,
                amplitude TEXT,
                highest TEXT,
                lowest TEXT,
                open_price TEXT,
                close_price TEXT)''')

driver = webdriver.Chrome()
#选择要爬取的界面,将注释去掉
#沪深京A股
#driver.get("https://quote.eastmoney.com/center/gridlist.html#hs_a_board")
#上证A股
#driver.get("https://quote.eastmoney.com/center/gridlist.html#sh_a_board")
#深证A股
#driver.get("https://quote.eastmoney.com/center/gridlist.html#sz_a_board")

# 爬取前4页股票信息
for page in range(1, 5): #爬取4页
    print(f"正在爬取第 {page} 页股票信息")
    
    # 定位所有股票信息的元素
    stocks_list = driver.find_elements(By.XPATH,"//div[@class='listview full']//tbody//tr")  

    # 打印股票信息
    for stock in stocks_list:
        stock_id = stock.find_element(By.XPATH,'.//td[1]').text
        stock_code = stock.find_element(By.XPATH,'.//td[2]/a').text
        stock_name= stock.find_element(By.XPATH,'.//td[3]/a').text
        stock_latest_price= stock.find_element(By.XPATH,'.//td[5]//span').text
        stock_change_percent= stock.find_element(By.XPATH,'.//td[6]//span').text
        stock_change_amount= stock.find_element(By.XPATH,'.//td[7]//span').text
        stock_volume= stock.find_element(By.XPATH,'.//td[8]').text
        stock_turnover= stock.find_element(By.XPATH,'.//td[9]').text
        stock_amplitude= stock.find_element(By.XPATH,'.//td[10]').text
        stock_highest= stock.find_element(By.XPATH,'.//td[11]//span').text
        stock_lowest= stock.find_element(By.XPATH,'.//td[12]//span').text
        stock_open_price= stock.find_element(By.XPATH,'.//td[13]//span').text
        stock_close_price= stock.find_element(By.XPATH,'.//td[14]').text
        print(f"序号: {stock_id}")
        print(f"股票代码: {stock_code}")
        print(f"股票名称: {stock_name}")
        print(f"最新报价: {stock_latest_price}")
        print(f"涨跌幅: {stock_change_percent}")
        print(f"涨跌额: {stock_change_amount}")
        print(f"成交量: {stock_volume}")
        print(f"成交额: {stock_turnover}")
        print(f"振幅: {stock_amplitude}")
        print(f"最高: {stock_highest}")
        print(f"最低: {stock_lowest}")
        print(f"今开: {stock_open_price}")
        print(f"昨收: {stock_close_price}")
        print("-" * 60)
        cursor.execute("INSERT INTO stocks (code, name, latest_price, change_percent, change_amount, volume, turnover, amplitude, highest, lowest, open_price, close_price) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)",
                    (stock_code, stock_name, stock_latest_price, stock_change_percent, stock_change_amount, stock_volume, stock_turnover, stock_amplitude, stock_highest, stock_lowest, stock_open_price, stock_close_price))
    conn.commit()
    print("数据已存入数据库")

    # 点击下一页按钮
    next_page_button = driver.find_element(By.XPATH, '//*[@id="main-table_paginate"]/a[2]')
    action = ActionChains(driver)
    time.sleep(5)
    action.move_to_element(next_page_button).perform()
    next_page_button.click()

    time.sleep(5)  
conn.close()
# 关闭浏览器
driver.quit()

  • 输出结果(4页*20=80条):
    沪京深A股:


    上证A股:


    深证A股:

  • 心得体会:
    这次股票网的爬取建立在上次scrapy爬取动态网页失败的基础上,再加上之前商城爬取的selenium相关经验,搭建框架相对比较快,且xpath也有上次现成的,只是chrome的驱动一直打不开网页,确认了驱动与Google的版本也确认匹配,后期重装最新版的谷歌与驱动打开网页也时好时坏,最后用edge替代完成了代码调试之后,此处提交更换为chrome驱动的代码形式。本次实验重温了selenium爬取网络操作的过程,对代码与真实模拟体验更加深刻。

  • 作业:

  • 要求:

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

  • 输出信息:MYSQL数据库存储和输出格式

  • Gitee文件夹链接
    Git文件夹

Id cCourse cCollege cTeacher cTeam cCount cProcess cBrief
1 Python数据分析与展示 北京理工大学 嵩天 嵩天 470 2020年11月17日 ~ 2020年12月29日 “我们正步入一个数据或许比软件更重要的新时代。——Tim O'Reilly” ……
2......
  • 代码:
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
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.common.action_chains import ActionChains
import time
import random
import sqlite3
from selenium.common.exceptions import NoSuchElementException
conn = sqlite3.connect('mooc.db')
cursor = conn.cursor()
cursor.execute('''CREATE TABLE IF NOT EXISTS mooc (
               id INTEGER PRIMARY KEY,
               course TEXT,
               college TEXT,
               teacher TEXT,
               team TEXT,
               count INTEGER,
               process TEXT,
               brief TEXT
)''')
driver = webdriver.Chrome()
#最大化浏览器
driver.maximize_window()
driver.get("https://www.icourse163.org/")
time.sleep(3)
#点击登录按钮
login_button = driver.find_element(By.XPATH,'//*[@id="app"]/div/div/div[1]/div[3]/div[3]/div')  
login_button.click()
time.sleep(8)
#反爬
driver.switch_to.default_content()
driver.switch_to.frame(driver.find_elements(By.TAG_NAME,'iframe')[0])
time.sleep(4)
#输入用户名
username=driver.find_element(By.XPATH,'/html/body/div[2]/div[2]/div[2]/form/div/div[2]/div[2]/input')
username.clear()
username.send_keys("15280076685")
time.sleep(3)
#输入密码 
password=driver.find_element(By.XPATH,'/html/body/div[2]/div[2]/div[2]/form/div/div[4]/div[2]/input[2]')
password.send_keys("12345678")
 
time.sleep(3)

login=driver.find_element(By.ID,"submitBtn")
login.click()
time.sleep(2)
driver.switch_to.default_content()
time.sleep(10)

#搜索框
search_box = driver.find_element(By.XPATH,'/html/body/div[4]/div[1]/div/div/div/div/div[7]/div[1]/div/div/div[1]/div/div/div/div/div/div/input')
search_box.send_keys("python", Keys.RETURN)
# 声明一个list,存储dict
data_list = []

def start_spider():
    WebDriverWait(driver, 10).until(EC.presence_of_all_elements_located((By.XPATH, '//div[@class="m-course-list"]/div/div')))
    # 将滚动条拉到最下面的位置,因为往下拉才能将这一页的商品信息全部加载出来
    driver.execute_script('document.documentElement.scrollTop=10000')
    # 随机延迟,等下元素全部刷新
    time.sleep(random.randint(3, 6))
    driver.execute_script('document.documentElement.scrollTop=0')

    # 开始提取信息,找到ul标签下的全部li标签
    num = 0
    for link in driver.find_elements(By.XPATH, '//div[@class="m-course-list"]/div/div'):
        num += 1
        course_name = link.find_element(By.XPATH, './/span[@class=" u-course-name f-thide"]').text
        try:
            school_name = link.find_element(By.XPATH, './/a[@class="t21 f-fc9"]').text
        except NoSuchElementException:
            school_name = ''  
        try:
            teacher = link.find_element(By.XPATH, './/a[@class="t21 f-fc9"]').text
        except NoSuchElementException:
            teacher = ''
        try:
            team_member = link.find_element(By.XPATH, './/a[@class="t21 f-fc9"]').text
        except NoSuchElementException:
            team_member = ''
        try:
            join = link.find_element(By.XPATH, './/span[@class="hot"]').text.replace('参加', '')
        except NoSuchElementException:
            join = ''
        try:
            process = link.find_element(By.XPATH, './/span[@class="txt"]').text
        except NoSuchElementException:
            process = ''
        try:
            introduction = link.find_element(By.XPATH, './/span[@class="p5 brief f-ib f-f0 f-cb"]').text
        except NoSuchElementException:
            introduction = ''
        try:
            cursor.execute("INSERT INTO mooc (`id`, `course`, `college`, `teacher`, `team`, `count`, `process`, `brief`) VALUES (?, ?, ?, ?, ?, ?, ?, ?)",
                           (num, str(course_name), str(school_name), str(teacher), str(team_member), str(join), str(process), str(introduction)))
        except Exception as err:
            print("出现错误:", err)
        conn.commit()
        print("数据已存入数据库")

def main():

    start_spider()
if __name__ == '__main__':

    main()
    # 退出浏览器
    driver.quit()
conn.close()
  • 输出结果:

  • 心得体会:
    本次实验第一次体验登录的selenium操作过程,需要注意的是mooc网站的反爬机制以及防止个别条目因不存在相关属性而出现报错的问题需要写的异常处理,还有数据库属性格式,需要在导入数据库时转换成字符串形式,这段代码的编译与运行是一个比较漫长的过程,通过此次实验,对selenium模仿登录有了一定的认识,也巩固了其他以前操作过的相关知识。

  • 作业:

  • 要求:

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

  • 完成文档 华为云_大数据实时分析处理实验手册-Flume日志采集实验(部分)v2.docx 中的任务,即为下面5个任务,具体操作见文档。

  • 环境搭建:

  • 任务一:开通MapReduce服务

  • 实时分析开发实战****:

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

  • 任务二:配置Kafka

  • 任务三: 安装Flume客户端


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

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