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

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

码云链接:2022级数据采集与融合技术 - 码云 (gitee.com)


作业①:

  • 要求:

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

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

  • Gitee 文件夹链接:2022级数据采集与融合技术 - 码云 (gitee.com)

    序号 股票代码 股票名称 最新报价 涨跌幅 涨跌额 成交量 成交额 振幅 最高 最低 今开 昨收
    1 688093 N世华 28.47 62.22% 10.92 26.13万 7.6亿 22.34 32.0 28.08 30.2 17.55
    2......

(1)实验过程

1.编程思路:
graph TD A[开始] --> B[初始化driver] B --> C[建立与数据库的连接并创建表] C --> D[根据用户输入选择要爬取的股票类型与翻页次数] D --> E[爬取当前页股票数据并存入数据库中] E --> F[翻页至指定翻页次数] F --> G[结束]
2.F12网站数据分析:

由下图可以发现“沪深A股”、“上证A股”、“深证A股”3个板块的url不同,我选择根据键盘输入来更改对应的url

url1 = "http://quote.eastmoney.com/center/gridlist.html#hs_a_board"
url2 = "http://quote.eastmoney.com/center/gridlist.html#sh_a_board"
url3 = "https://quote.eastmoney.com/center/gridlist.html#sz_a_board"
print("请输入要爬取的股票类型对应的数字编号:")
print("1:沪深A股 2:上证A股 3:深圳A股")
keyno = eval(input())
if keyno == 1:
    url = url1
elif keyno == 2:
    url = url2
elif keyno == 3:
    url = url3
else:
    print("输入错误,请重新输入")
    exit()



使用XPath选择器提取股票代码、名称、最新报价、涨跌幅、成交量等信息

翻页逻辑

3.部分代码:

这段代码定义了 MySpider 类中的 processSpider 方法,是爬虫的核心功能,负责从指定的URL抓取股票数据。首先,它通过 time.sleep(3) 暂停3秒以等待页面加载,然后使用 self.driver.find_elements 方法和XPath选择器定位到包含股票信息的表格行。对于每一行,它进一步使用XPath选择器提取股票代码、名称、最新报价、涨跌幅、成交量等信息,并将这些信息存储到SQLite数据库中。如果存在下一页,代码将点击下一页按钮并递归调用 processSpider 方法继续爬取,直到达到用户设定的最大页面数(由于页数过多因此设定了键盘输入最大页数)。如果在尝试点击下一页时遇到异常(例如没有下一页或按钮不可点击),代码将尝试点击其他股票板块的标签页继续爬取。如果在爬取过程中遇到任何异常,它将打印错误信息。整个过程中,self.No 用于记录当前处理的行数,并在插入数据库时作为唯一标识符。

 def processSpider(self):
        try:
            time.sleep(3)
            print(self.driver.current_url)
            lis = self.driver.find_elements(By.XPATH,"//table[@id='table_wrapper-table']/tbody/tr")
            print(lis)
            for li in lis:
                try:
                    bStockNo = li.find_element(By.XPATH,".//td[position()=2]").text
                    bStockName = li.find_element(By.XPATH,".//td[position()=3]").text
                    bStockprice = li.find_element(By.XPATH,".//td[position()=5]").text
                    up = li.find_element(By.XPATH,".//td[position()=6]").text
                    up_num = li.find_element(By.XPATH,".//td[position()=7]").text
                    volume = li.find_element(By.XPATH,".//td[position()=8]").text
                    volume_num = li.find_element(By.XPATH,".//td[position()=9]").text
                    amplitude = li.find_element(By.XPATH,".//td[position()=10]").text
                    highest = li.find_element(By.XPATH,".//td[position()=11]").text
                    lowest = li.find_element(By.XPATH,".//td[position()=12]").text
                    today = li.find_element(By.XPATH,".//td[position()=13]").text
                    yesterday = li.find_element(By.XPATH,".//td[position()=14]").text
                except:
                    print("err5")
                self.No = self.No + 1
                no = str(self.No)
                while len(no) < 3:
                    no = "0" + no
                print(no)
                self.insertDB(no, bStockNo, bStockName, bStockprice, up, up_num, volume, volume_num, amplitude, highest, lowest, today, yesterday)
            try:
                nextpage = self.driver.find_element(By.XPATH,
                    "//div[@class='dataTables_wrapper']//div[@class='dataTables_paginate paging_input']//a[@class='next paginate_button']")
                time.sleep(6)
                if self.flag < self.max_pages:  # 检查是否达到最大爬取页面数
                    nextpage.click()
                    self.flag += 1
                    self.processSpider()
                else:
                    print("已达到设定的最大爬取页面数,停止翻页。")
            except:
                self.driver.find_element(By.XPATH,
                    "//div[@class='dataTables_wrapper']//div[@class='dataTables_paginate paging_input']//a[@class='next paginate_button disabled']")
                self.flag += 1
                if self.flag <= 3:
                    li=self.driver.find_elements(By.XPATH,"//ul[@class='tab-list clearfix']//li")[self.flag-1]
                    li.click()
                    time.sleep(2)
                    self.processSpider()

        except Exception as err:
            print(err)
            print("err7")
4.输出结果:

”沪深A股”

“上证A股”

“深证A股”

(2)心得体会

深入学习了Selenium框架的使用,特别是在处理Ajax网页数据爬取和等待HTML元素方面。通过实际操作,我掌握了如何使用Selenium查找HTML元素,以及如何将爬取的数据存储到MySQL数据库中。这道题相对下一题没有那么多的坑,相对容易。通过不断调试和优化,我最终成功实现了对“沪深A股”、“上证A股”、“深证A股”三个板块的股票数据信息的爬取,并存储到了数据库中。


作业②:

  • 要求:

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

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

    Id cCourse cCollege cTeacher cTeam cCount cProcess cBrief
    1 Python数据分析与展示 北京理工大学 嵩天 嵩天 470 2020年11月17日 ~ 2020年12月29日 “我们正步入一个数据或许比软件更重要的新时代。——Tim O'Reilly” 运用数据是精准刻画事物、呈现发展规律的主要手段,分析数据展示规律,把思想变得更精细! ——“弹指之间·享受创新”,通过8周学习,你将掌握利用Python语言表示、清洗、统计和展示数据的能力。
    2......

(1)实验过程

1.编程思路:
graph TD A[初始化driver] --> B[与mysql建立连接并创建数据表] B --> C[使用手机号和密码实现用户登录] C --> D[按用户给的关键词搜索课程并跳转] D --> E[进行翻页爬取数据并存入数据库中] E --> F[递归爬取直到最后一页]
2.关键要点
2.1模拟网站登录

如下图,mooc登入输入的账号密码在弹窗中,该弹窗的html代码段在 iframe 标签下的内联框架中,要用driver.switch_to.frame方法切换iframe,去该 iframe 标签下进行输入框查找,这里使用手机号登入:

 def login(self,account,password,loginurl):
        print("登录中")
        #获取登录页面
        self.driver.get(loginurl)
        iframe=self.driver.find_element(By.TAG_NAME,"iframe")
        self.driver.switch_to.frame(iframe)
        # 定位到输入账号的位置,输入账号/html/body/div[2]/div[2]/div[2]/form/div/div[2]/div[2]/input  //*[@id="phoneipt"]
        self.driver.find_element(By.XPATH,'//*[@id="phoneipt"]').send_keys(account)
        #定位到输入密码的位置,输入密码
        self.driver.find_element(By.XPATH,"/html/body/div[2]/div[2]/div[2]/form/div/div[4]/div[2]/input[2]").send_keys(password)
        #点击登录按钮
        self.driver.find_element(By.XPATH,"/html/body/div[2]/div[2]/div[2]/form/div/div[6]/a").click()
        print("登录成功")
        time.sleep(5)
2.2窗口来回切换

由于cProcess只有在课程的详情页才有,需要点击进入详情页爬取数据后,返回原窗口。

在打开一个新窗口后,会先保存原始窗口的句柄,然后切换到新窗口进行操作。操作完成后,再通过保存的原始窗口句柄切换回原始窗口。

  #切换到新窗口
    def switch_new_window(self):
        new_window=self.driver.window_handles[-1]#返回最新句柄(所有句柄的最后一个)
        #切换到当前最新打开的窗口
        self.driver.switch_to.window(new_window)

    # 切换到原窗口
    def switch_origin_window(self):
        self.driver.close()
        origin_window=self.driver.window_handles[0]#返回最新句柄(所有句柄的第一个)
        self.driver.switch_to.window(origin_window)
3.部分代码
3.1实现翻页

当下一页的按钮class属性为th-bk-disable-gh无下一页。

            try:
                #查找是否可以翻页,如果找到不可翻页标记则说明到了最后一页,程序结束,否则进入except
                self.driver.find_element(By.XPATH,"//li[@class='ux-pager_btn ux-pager_btn__next']/a[@class='th-bk-disable-gh']")
                print("爬取结束")
            except:
                #点击翻页,然后递归调用download
                nextpage=self.driver.find_element(By.XPATH,"//li[@class='ux-pager_btn ux-pager_btn__next']/a[@class='th-bk-main-gh']")
                nextpage.click()
                time.sleep(3)
                self.download()
3.2实现搜索
    def choose(self,key,url):
        #获取网页
        print("正在搜索关键词{}......".format(key))
        self.driver.get(url)
        time.sleep(1)
        #定位到搜索框,将关键词输入到搜索框/html/body/div[4]/div[1]/div/div/div/div/div[7]/div[1]/div/div[1]/div[1]/span
        keyInput = self.driver.find_element(By.XPATH,"/html/body/div[4]/div[1]/div/div/div/div/div[7]/div[1]/div/div[1]/div[1]/span/input")
        keyInput.send_keys(key)
        keyInput.send_keys(Keys.ENTER)
        time.sleep(2)
        print("搜索完成,准备开始爬取")
3.3爬取课程信息
#统计爬取的当前页
            self.page+=1
            print("爬取第{}页".format(self.page))
            #爬取的各个课程数据列表
            datalist=self.driver.find_elements(By.XPATH,"//div[@class='cnt f-pr']")
            time.sleep(2)
            for data in datalist:
                # 有些课程格式不符合规范,如没有开课学校的,使用except略过,否则会因为格式问题报错,影响爬取
                try:
                    #待爬取的各项数据
                    cCource=data.find_element(By.XPATH,"./div[@class='t1 f-f0 f-cb first-row']").text
                    cCollege=data.find_element(By.XPATH,".//a[@class='t21 f-fc9']").text
                    cTeacher=data.find_element(By.XPATH,".//a[@class='f-fc9']").text
                    cTeam=data.find_element(By.XPATH,".//a[@class='f-fc9']").text
                    cCount=data.find_element(By.XPATH,".//span[@class='hot']").text
                    cClick = data
                    cClick.click()
                    time.sleep(5)
                    self.driver.switch_to.window(self.driver.window_handles[-1])
                    WebDriverWait(self.driver, 15, 0.5).until(EC.presence_of_element_located((By.XPATH, "//*[@id='g-body']/div[1]/div")))
                    cProcess = self.driver.find_element(By.XPATH,"//div[@class='course-enroll-info_course-info_term-info_term-time']//span[2]").text
                    cBrief = self.driver.find_element(By.XPATH, "//div[@class='course-heading-intro_intro']").text
                    self.driver.switch_to.window(self.driver.window_handles[0])
                    #统计爬取的课程个数,用做序号数据项
                    self.no += 1
                    print(self.no,cCource,cCollege,cTeacher,cTeam,cCount,cProcess,cBrief)
                    #将爬取的数据插入到mysql数据库中
                    self.cursor.execute("insert into mooc (id,cCource,cCollege,cTeacher,cTeam,cCount,cProcess,cBrief) values(?,?,?,?,?,?,?,?)", (self.no, cCource, cCollege, cTeacher, cTeam, cCount, cProcess, cBrief))
                    #提交到命令行执行
                    self.con.commit()
                    #简单记录爬取过程
                    print(cCource)
                except:
                    pass
4.输出结果:

(2)心得体会

我面临的主要挑战是如何模拟网站登录以及如何在新旧窗口之间进行切换。学会了如何使用Selenium的switch_to.frame方法来处理iframe中的元素,这对于模拟登录过程至关重要。此外,我还学会了如何在新窗口打开后保存原始窗口的句柄,并在操作完成后切换回原始窗口。login方法实现打开登录页面,切换到iframe,输入账号和密码,然后点击登录按钮。choose 方法根据用户输入的关键词,打开指定的URL,并在搜索框中输入关键词进行搜索。download 方法爬取当前页面的课程数据,并点击课程链接进入详情页获取更多信息。将爬取的数据插入到数据库中。检查是否存在下一页,如果存在,则点击下一页继续爬取;否则结束爬取。

难点主要在于模拟登录过程和窗口切换。在模拟登录过程中,由于刚开始没有切换到iframe的元素,一直出现无法找到对应的Xpath语句的错误。后面分析了登录页面的HTML结构,发现需要先切换到iframe的元素。然后,使用Selenium的switch_to.frame方法切换到iframe,并定位到账号和密码输入框,输入凭据并提交表单。登录成功后,面临要进行窗口切换的问题,保存了新窗口的句柄,并在完成详情页数据爬取后,使用保存的句柄切换回原始窗口。这个过程需要精确的异常处理和元素定位,通过不断测试和调整,我最终成功实现了这一过程。


作业③:

  • o 要求:

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

    • 完成文档 华为云_大数据实时分析处理实验手册-Flume 日志采集实验(部

    分)v2.docx 中的任务,即为下面 5 个任务,具体操作见文档。

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


(1)实验过程

Flume是流式日志采集工具,Flume提供对数据进行简单处理并且写到各种数据接受方
(可定制)的能力,Flume提供从本地文件 (spooling directory source)、实时日志 (taildir、
exec)、REST消息、 Thrift 、Avro、Syslog、Kafka等数据源上收集数据的能力。

1.环境搭建:
任务一:开通 MapReduce 服务

2.实时分析开发实战
任务一:Python 脚本生成测试数据

步骤1登录MRS的master节点服务器
步骤2编写Python脚本

步骤3创建存放测试数据的目录
步骤4执行脚本测试

任务二:配置 Kafka

步骤1进入MRS Manager集群管理
步骤2下载Kafka客户端

步骤3校验下载的客户端文件包

步骤4安装Kafka运行环境

步骤5安装Kafka客户端

步骤6设置环境变量
步骤7在kafka中创建topic
步骤8查看topic信息

任务三: 安装 Flume 客户端

步骤1进入MRS Manager集群管理
步骤2下载Flume客户端

步骤3校验下载的客户端文件包

步骤4安装Flume运行环境

步骤5安装Flume客户端

步骤6重启Flume服务

任务四:配置 Flume 采集数据

步骤1修改配置文件

步骤2 创建消费者消费kafka中的数据

(2)心得体会

通过学习Flume日志采集实验手册,了解了什么是Flume,对其有了一定的认知,初步掌握了Flume日志采集相关服务的使用。通过华为云实验深入了解了大数据相关服务以及实时分析处理的实际操作,掌握了Xshell工具的使用技巧。针对文档中的任务,我逐一进行了操作。通过完成这些任务,我不仅掌握了大数据相关服务和工具的使用,还对实时数据处理的流程和方法有了更深入的了解,提升了我的实际操作能力和对大数据处理的整体认识。


posted @ 2024-11-13 13:42  耶~  阅读(31)  评论(0编辑  收藏  举报