程序员的资源宝库

网站首页 > gitee 正文

数据采集与融合实践第四次实践作业

sanyeah 2024-03-29 15:22:10 gitee 6 ℃ 0 评论

作业1

Selenium爬取股票信息

  • Gitte文件夹链接:https://gitee.com/prettykuromi/102102137/tree/master/作业4/问题1
  • 本次作业要爬取“沪深 A 股”、“上证 A 股”、“深证 A 股”3 个板块的股票数据信息,分析url结构,
    https://quote.eastmoney.com/center/gridlist.html#hs_a_board
    更换板块,实际上是更换url在#后携带的参数
  • 实现翻页,在每次翻页时获取页面中数据,注意翻页时增加time.sleep,以防爬取数据过快对网站造成干扰
driver = webdriver.Chrome()
    url = f'http://quote.eastmoney.com/center/gridlist.html#{board}_a_board'
    driver.get(url)
    for i in range(10):
        # 等待页面成功加载
        wait = WebDriverWait(driver, 10)  # 设置显式等待时间为10秒
        element = wait.until(
            EC.visibility_of_element_located((By.CSS_SELECTOR, ".next")))  # 等待元素可见
        html = driver.page_source
        findElement(html,board)
        # 实现翻页
        time.sleep(1)
        searchbutton = driver.find_element(By.CSS_SELECTOR, ".next")
        searchbutton.click()
  • 分析页面html结构,所需信息在table中存储,获取较为简单,编写如下函数从页面中获取数据
def findElement(html,board):
    soup = BeautifulSoup(html, 'html.parser')
    global rows
    try:
        # 尽量精确查找
        row=''
        tr_elements = soup.select('table[id="table_wrapper-table"] tbody tr')
        for tr_element in tr_elements:
            td_elements=tr_element.select('td')
            if(board=='hs'):
                board="沪深京A股票"
            elif(board=='sh'):
                board="上证A股"
            elif(board=='sz'):
                board="深证A股"
            No=td_elements[0].text.strip()
            StockId = td_elements[1].text.strip()
            Name = td_elements[2].text.strip()
            NewPrice = td_elements[4].text.strip()
            UpDown = td_elements[5].text.strip()
            UpDownPrice = td_elements[6].text.strip()
            DealNum = td_elements[7].text.strip()
            DealPrice = td_elements[8].text.strip()
            Up = td_elements[9].text.strip()
            row = '-'.join([board, No, StockId, Name, NewPrice, UpDown, UpDownPrice, DealNum, DealPrice, Up])
            rows.append(row)
    except Exception as err:
        print(err)
    return rows
  • 获取所有数据后,需要将数据存储到本地数据库中
def saveData():
    global rows
    con = pymysql.connect(host="127.0.0.1", port=3306, user="root", passwd="admin123", db="mydb",
                                       charset="utf8")
    cursor =con.cursor(pymysql.cursors.DictCursor)
    #删除已有表
    cursor.execute("drop table selenium_stocks")
    #新建表
    cursor.execute("CREATE TABLE selenium_stocks (\
                    Board VARCHAR(45),\
                    No VARCHAR(45),\
                    StockId VARCHAR(45),\
                    Name VARCHAR(45),\
                    NewPrice VARCHAR(45),\
                    UpDown VARCHAR(45),\
                    UpDownPrice VARCHAR(45),\
                    DealNum VARCHAR(45),\
                    DealPrice VARCHAR(45),\
                    Up VARCHAR(45)\
                    )")
    # 向表中插入数据
    for row in rows:
        print(row)
        data = row.split('-')
        cursor.execute(
            "INSERT INTO selenium_stocks (Board, No, StockId, Name, NewPrice, UpDown, UpDownPrice, DealNum, DealPrice, Up) VALUES (%s, %s, %s, %s, %s, %s, %s, %s, %s, %s)",
            (data[0], data[1], data[2], data[3], data[4], data[5], data[6], data[7], data[8], data[9])
        )
    con.commit()
  • 运行程序,成功爬取数据,使用MySQLWorkBench查看数据

心得体会

  1. 爬取数据时,一定要注意观察url结构
  2. 存储数据到数据库时,要注意数据类型一致
  3. 爬取页面实现翻页时,为防止对网站造成骚扰,一定要设置time.sleep,同时也防止爬取页面过于频繁导致IP地址被封

作业2

实现用户模拟登录并使用Selenium爬取MOOC数据

  • Gittee文件夹链接:https://gitee.com/prettykuromi/102102137/tree/master/作业4/问题2
  • 首先需要实现登录,思路:进入页面后点击登录按钮,由于MOOC网站没有设置验证码,因此找到对应输入框输入手机号和密码后点击登录按钮即可实现登录
    注意:所要查找的元素处于一个iframe标签下(通常称为网页布局嵌套),而一般webdriver要操作页面元素需要在Top Window的状态下,当浏览器出现iframe时,用正常的元素定位是没有效果的,需要将页面装换到iframe下再对页面元素进行操作
driver = webdriver.Chrome()
url = 'https://www.icourse163.org/'
driver.get(url)
# 等待页面成功加载
wait = WebDriverWait(driver, 10)
element = wait.until(EC.visibility_of_element_located((By.CSS_SELECTOR, ".navLoginBtn")))
# 找到登录按钮并点击
loginbutton = driver.find_element(By.CSS_SELECTOR, ".navLoginBtn")
loginbutton.click()
# 等待登录页面加载成功
time.sleep(2)
html = driver.page_source
# 定位到iframe
iframe = driver.find_element(By.TAG_NAME, "iframe")
# 句柄切换进iframe
driver.switch_to.frame(iframe)
# 找到手机号输入框并输入内容
phone_input = driver.find_element(By.ID, "phoneipt").send_keys("19835522936")
# 找到密码输入框并输入内容
psd_input = driver.find_element(By.CSS_SELECTOR, ".j-inputtext").send_keys("3310232004chen!")
# 找到登录按钮并点击
loginbutton = driver.find_element(By.ID, "submitBtn")
loginbutton.click()
# 等待登录成功页面加载完成
time.sleep(5)
# 跳出iframe
driver.switch_to.default_content()
  • 成功登录后,即可点击搜索框输入想搜索的内容并跳转即可
# 等待登录成功页面加载完成
time.sleep(5)
# 跳出iframe
driver.switch_to.default_content()

# 等待页面成功加载
wait = WebDriverWait(driver, 10)
element = wait.until(EC.visibility_of_element_located((By.CSS_SELECTOR, ".inputtxt")))

# 找到输入框并输入内容
phone_input = driver.find_element(By.CSS_SELECTOR, ".inputtxt")
phone_input.send_keys("计算机")
# 点击搜索按钮
searchbutton = driver.find_element(By.CSS_SELECTOR, ".j-searchBtn")
searchbutton.click()

time.sleep(2)
  • 进入详情页面后,此时观察页面结构,发现有部分“广告”不符合我们爬取大学网课的要求

  • 因此爬取数据时需要加以判断,如果不符合我们的要求就不爬取数据并存储到数据库

div_elements = soup.select('div[class="m-course-list"]>div>div')

for div_element in div_elements:
    cCourse = cCollege = cTeacher = cTeam = cCount = cProcess = cBrief = ""
    #对每个数据字段都加以判断,因此代码较繁琐
    course_name = div_element.select_one('span[class="u-course-name f-thide"]')
    if course_name is not None:
        cCourse = course_name.text.strip()
    else:
        continue
    college_name = div_element.select_one('a[class="t21 f-fc9"]')
    if college_name is not None:
        cCollege = college_name.text.strip()
    else:
        continue
    teacher_name = div_element.select_one('a[class="f-fc9"]')
    if teacher_name is not None:
        cTeacher = teacher_name.text.strip()
    else:
        continue
    team_name = div_element.select_one('span[class="f-fc9"]')
    if team_name is not None:
        cTeam = team_name.text.replace('、', ' ').strip()
    else:
        continue
    count_num = div_element.select_one('span[class="hot"]')
    if count_num is not None:
        cCount = count_num.text.replace('人参加', '')
    else:
        continue
    process_info = div_element.select_one('span[class="txt"]')
    if process_info is not None:
        cProcess = process_info.text
    else:
        continue
    brief_info = div_element.select_one('span[class="p5 brief f-ib f-f0 f-cb"]')
    if brief_info is not None:
        cBrief = brief_info.text
    else:
        continue
    row = cCourse + "-" + cCollege + "-" + cTeacher + "-" + cTeam + "-" + str(
        cCount) + "-" + cProcess + "-" + cBrief
    rows.append(row)
  • 存储数据到数据库中
def saveData():
    global rows
    con = pymysql.connect(host="127.0.0.1", port=3306, user="root", passwd="admin123", db="mydb",
                                       charset="utf8")
    cursor =con.cursor(pymysql.cursors.DictCursor)
    #删除已有表
    cursor.execute("drop table mooc")
    #新建表
    cursor.execute('''
                CREATE TABLE mooc (
              Id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
              cCourse VARCHAR(45),
              cCollege VARCHAR(45),
              cTeacher VARCHAR(45),
              cTeam VARCHAR(255),
              cCount VARCHAR(45),
              cProcess VARCHAR(45),
              cBrief VARCHAR(255)
            );
    ''')
    # 向表中插入数据
    for row in rows:
        print(row)
        data = row.split('-')
        cursor.execute(
            "INSERT INTO mooc (cCourse,cCollege,cTeacher,cTeam,cCount,cProcess,cBrief) VALUES (%s, %s, %s, %s, %s, %s, %s)",
            (data[0], data[1], data[2], data[3], data[4], data[5], data[6])
        )
    con.commit()

  • 继续实现翻页,同样需要注意翻页不能过快
    for i in range(10):
        # 等待页面成功加载
        wait = WebDriverWait(driver, 10)  # 设置显式等待时间为10秒
        element = wait.until(
            EC.visibility_of_element_located((By.CSS_SELECTOR, ".th-bk-main-gh")))  # 等待元素可见
        html = driver.page_source
        findElement(html)
        # 实现翻页
        time.sleep(1)
        nextbutton = driver.find_element(By.CSS_SELECTOR, ".th-bk-main-gh")
        nextbutton.click()
  • 运行程序,成功获取数据并存储到数据库中,部分数据展示如下:

心得体会

  • 对于这种特殊的有弹窗的页面,需要额外处理,不然无法定位到输入框并输入数据
  • 获取数据时要注意筛选掉不需要的数据
  • 存储数据到数据表时,要注意字段长度限制,比如课程描述的字段大多超过45个字符,如果依然设为VARCHAR(45)就会导致报错

作业3

Flume日志采集实验

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

  2. Python脚本生成测试数据

  • 安装Xshell,课程资料中的Xshell下载运行时会提示更新版本,因此前往官网下载最新版的Xshell
  • 连接服务器并输入自己的IP地址和用户名、密码
  • 安装Xftp,移动文件,执行python命令成功生成数据
  1. 配置 Kafka
  • 在kafka中创建topic并查看topic信息
  1. 安装 Flume 客户端
  • 在MRS Manager集群管理界面中下载Flume客户端,然后进行一系列配置操作,最终成功重启服务。
  1. 配置 Flume 采集数据
  • 修改配置文件后登录Master节点执行命令
  • 在右选项卡组重新打开会话,重新执行python脚本命令,一样可以生成数据

心得体会

  1. 申请服务器并进行相关配置时一定要认真仔细,实验结束后及时释放资源避免产生额外费用
  2. 对服务器来说,数据安全是重中之重,在完成本次实验中也体会到了该点,有大量的安全认证确保数据安全
  3. 服务器的高效、可靠、安全性是正常私人电脑无法匹配的,因此在后续学习工作中要善于使用服务器

Tags:

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表