linzeX

数据采集第五次大作业

作业一

  • 要求:
    熟练掌握 Selenium 查找HTML元素、爬取Ajax网页数据、等待HTML元素等内容。
    使用Selenium框架爬取京东商城某类商品信息及图片。

  • 候选网站:http://www.jd.com/

  • 输出内容

    bNo bTitl bPrice bNote bFile
    000001 三星Galaxy 9199.00 三星Galaxy Note20 Ultra 5G.. 000001.jpg
    000002 ~ ~ ~ ~

    结果展示

    • 思路:
      • 第一步 :打开京东官网利用xpath工具查看输入框的xpath路径与确定按钮的xpath路径
        输入框:

        提交按钮:

      • 第二步:以python为关键字 构造一个搜索商品函数

        KEYWORD = 'python'##商品关键字
        def startsearch():##搜索商品函数
           print("搜索商品"+KEYWORD)
           try:
               url = "http://www.jd.com/"##jd官网
               browser.get(url)##加载页面
               time.sleep(3)##等待页面加载
               ##获取输入框元素
               input=browser.find_elements_by_xpath("/html[@class='o2_mini csstransitions cssanimations o2_webkit o2_chrome o2_latest']/body[@class='index o2_window']/div[@class='mod_container']/div[@id='header']/div[@class='w']/div[@id='search']/div[@class='search-m']/div[@class='form']/input[@id='key']")[0]
               input.clear()##清除内容
               input.send_keys(KEYWORD)##输入关键字
               ##获取确定按钮
               submit=browser.find_elements_by_xpath("/html[@class='o2_mini csstransitions cssanimations o2_webkit o2_chrome o2_latest']/body[@class='index o2_window']/div[@class='mod_container']/div[@id='header']/div[@class='w']/div[@id='search']/div[@class='search-m']/div[@class='form']/button[@class='button']")[0]
               submit.click()##点击确认按钮
               time.sleep(3)##等待页面内容加载
               get_products()##爬取商品函数
           except TimeoutException:
               print('LinkFail')
        
      • 第三步:根据xpath工具获取商品信息路径构造爬取函数,由于京东商品信息都是动态加载的,需要先滑动滚动条让商品加载,但注意如果滑动过快也会导致部分商品信息没有加载,故需要先设置缓慢滑动滚动条,然后再进行xpath路径爬取

        def get_products():##爬取商品函数
            global sum ##计数
            time.sleep(5)##先等待页面加载
            js = "var q=document.documentElement.scrollTop=" ##js语句
            for i in range(1,20):  ##该循环控制滚动条间隔下滑500像素20次
                browser.execute_script(js+str(i*500))
                time.sleep(0.5)
            list=browser.find_elements_by_xpath('//div[@id="J_goodsList"]/ul/li')##先获取每个商品的标签
            ##根据结点路径查找需要的信息     
            for i in list:
                price= i.find_elements_by_xpath(".//div/div[@class='p-price']/strong/i")
                name=i.find_elements_by_xpath(".//div/div[@class='p-name']/a/em")
                img=i.find_elements_by_xpath(".//div/div[@class='p-img']/a/img")
                note=i.find_elements_by_xpath(".//div/div[@class='p-name']")
                insert(sum, name[0].text, price[0].text, note[0].text, img[0].get_attribute('src'))
                sum+=1 
                print('>-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------<')
         ```
        
        
      • 第四步:构造数据库相关函数

         def DBinit():##初始化函数,存在则先删除,然后创建
             try:
                 ##连接数据库 user用户名password密码database数据库名
                 con = pymssql.connect(host='localhost', user='lzx', password='lzx', database='lzx_')
                 cursor = con.cursor()
                 ##删除表
                 cursor.execute('drop table EXP51')
                 con.commit()
             except Exception as ex:
                 print(ex)
             try:
                 ##创建表,由于字段信息的长度差距极大,故都设置为500长度
                 cursor.execute(
                     "create table EXP51 (bNo varchar(500),bTitle varchar(500),bPrice varchar(500),bNote varchar(500),bFile varchar(500))")
                 ##提交并关闭
                 con.commit()
                 con.close()
             except Exception as ex:
                 print(ex)
         def insert(bNo,bTitle,bPrice,bNote,bFile):##插入函数
             try:
                 # 链接数据库
                 con = pymssql.connect(host='localhost', user='lzx', password='lzx', database='lzx_')
                 cursor =con.cursor()
                 ##插入数据
                 cursor.execute(
                     "INSERT INTO EXP51(bNo, bTitle,  bPrice,bNote,bFile) VALUES ('%s','%s','%s','%s','%s')" %
                     (bNo,bTitle,bPrice,bNote,bFile))
                 ##提交
                 con.commit()
             except Exception as ex:
                 print(ex)
        
    • 数据库截图:
  • 码云链接
    ----作业1-----

    心得体会

    网页动态加载,需要控制滑动滚动条下拉的同时需要设置停顿,让页面有足够时间完全加载
    注意查找元素方法的细节,如返回的是元素本身还是元素列表
    了解了xpath中 './/' , './' , '//' 的区别

作业二

  • 要求
    熟练掌握 Selenium 查找HTML元素、实现用户模拟登录、爬取Ajax网页数据、等待
    HTML元素等内容。
    使用Selenium框架+MySQL爬取中国mooc网课程资源信息(课程号、课程名称、教学
    进度、课程状态,课程图片地址),同时存储图片到本地项目根目录下的imgs文件夹
    中,图片的名称用课程名来存储。

  • 候选网站:中国mooc网:https://www.icourse163.org

  • 输出内容
    MYSQL数据库存储和输出格式
    表头应是英文命名例如:课程号ID,课程名称:cCourse……,由同学们自行定义

    结果展示

  • 思路:

    • 第一步:首先确定登录mooc流程
      • 点击登录注册按钮
      • 点击其他登录方式
      • 点击手机号登录
      • 输入账号密码后点击登录
      • 点击个人中心
      • 然后就可以得到所需要的课程信息页面
    • 第二步:设计自动操作代码
      • 先贴代码
        def startspider():##自动点击输入函数
            try:
                url = "https://www.icourse163.org"
                browser.get(url)
                time.sleep(3)
                ##点击登录注册按钮
                go=browser.find_elements_by_xpath("//div[@class='_3uWA6']")[0]
                go.click()
                ##点击其他方式登录
                gogo=browser.find_elements_by_xpath("//div[@class='mooc-login-set-wrapper']/div[@class='mooc-login-set']/div[@class='ux-login-set-scan-code f-pr']/div[@class='ux-login-set-scan-code_ft']/span[@class='ux-login-set-scan-code_ft_back']")[0]
                gogo.click()
                ##点击手机号登录
                gogogo=browser.find_elements_by_xpath("//div[@class='mooc-login-set-wrapper']/div[@class='mooc-login-set']/div[@class='ux-login-set-login-set-panel']/div[@class='login-set-panel']/div[@class='login-set-panel-login']/div[@class='ux-urs-login-urs-tab-login f-pr']/div[@class='ux-urs-login-urs-tabs']/div[@class='ux-tabs-underline']/ul[@class='ux-tabs-underline_hd']/li[2]")[0]
                gogogo.click()
                ##由于账户密码输入框和提交按钮处于iframe标签下的#document页面中,无法通过直接的xpath搜索得到
                ##需要先将当前的browser页面内容转换为#document内的内容,再根据#document的标签进行xpath搜索
                ##先通过xpath找到iframe标签,然后进行转换操作
                wait.until(
                    EC.frame_to_be_available_and_switch_to_it((By.XPATH, "//div[@class='ux-login-set-container']/iframe"))
                )
                ##找到账号输入框,输入账号
                loginname=browser.find_elements_by_xpath("//input[@type='tel']")[0]
                loginname.send_keys('15280057181')
                time.sleep(1)
                ##找到密码输入框,输入密码
                password = browser.find_elements_by_xpath("//input[@type='password']")[1]
                password.send_keys('lzx2001525')
                time.sleep(1)
                ##点击提交按钮
                submit=browser.find_elements_by_xpath("//a[@id='submitBtn']")[0]
                submit.click()
                time.sleep(4)
                ##点击个人中心
                gogogogogo = browser.find_elements_by_xpath("//a[@target='_top']/span[@class='nav']")[2]
                gogogogogo.click()
                ##等待页面内容加载
                time.sleep(3)
                ##爬取函数
                get_item()
            except TimeoutException:
                print('LinkFail')
        
      • 点击登录注册,点击其他方式登录,点击手机号登录都可以按正常的xpath找到元素然后点击
        (需要注意mooc网的标签id是会不断变化的,xpath定位规则需要做一些删改)
        但是当想输入账号密码时却无法找到元素,经过排查后发现账号密码输入框是以一个新的html页面形式镶嵌在iframe标签下的#document中,
        之后找到方法可以先将当前的selenium页面资源转换为#document内的页面内容,此时用find_elements_by_xpath方法查找的内容就是#document内的内容,可以直接进行xpath查找
    • 第三步:设计爬取信息代码
       def get_item():##爬取课程信息
          for i in range(4):##这里爬取前四页
              time.sleep(3)##等待内容加载
              ##先获取每个课程标签
              list=browser.find_elements_by_xpath("//div[@id='g-container']/div[@id='g-body']/div[@id='j-home-content']/div[@class='main-content f-cb']/div[@class='main-box f-fl']/div[@id='j-module-box']/div/div[@class='g-flow f-cb']/div[@class='g-mn2']/div[@class='g-mn2c']/div[@class='m-mcdoc']/div[@id='j-cnt1']/div[@id='j-coursewrap']/div[@class='course-panel-wrapper']/div[@class='course-panel-body-wrapper']/div[@class='course-card-wrapper']")
              for i in list:
                  ##根据标签路径查找
                  name= i.find_elements_by_xpath("./div[@class='box']/a[@class='ga-click']/div[@class='body']/div[@class='common-info-wrapper common-info-wrapper-fix-height']/div[@class='title']/div[@class='text']/span[@class='text']")[0]
                  school=i.find_elements_by_xpath("./div[@class='box']/a[@class='ga-click']/div[@class='body']/div[@class='common-info-wrapper common-info-wrapper-fix-height']/div[@class='school']/a")[0]
                  learn=i.find_elements_by_xpath("./div[@class='box']/a[@class='ga-click']/div[@class='body']/div[@class='personal-info']/div[@class='course-progress']/div[@class='status']/div[@class='text']/a/span[@class='course-progress-text-span']")[0]
                  status=i.find_elements_by_xpath("./div[@class='box']/a[@class='ga-click']/div[@class='body']/div[@class='personal-info']/div[@class='course-status']")[0]
                  url=i.find_elements_by_xpath("./div[@class='box']/a")[0]
                  ##利用get_attribute获取href信息
                  insert(name.text, school.text, learn.text, status.text,url.get_attribute('href'))
                  ##保存文件路径
                  filename = "D:/数据采集代码/实验五/作业2/imgs/"+ str(name.text)+str(school.text) + ".jpg"
                  ##保存文件
                  urllib.request.urlretrieve(str(url.get_attribute('src')), filename)
                  print('>-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------<')
              ##点击下一页
              browser.find_elements_by_xpath("//div[@class='g-mn2c']/div[@class='m-mcdoc']/div[@id='j-cnt1']/div[@id='j-coursewrap']/div[@class='course-panel-wrapper']/div[@class='course-panel-foot-wrapper']/ul[@class='ux-pager']/li[@class='ux-pager_btn ux-pager_btn__next']/a[@class='th-bk-main-gh']")[0].click()
      
    • 第四步:设计数据库代码
      与第一题类似,略
  • 数据库截图

  • 保存图片截图

  • 码云链接
    ------作业2-----

心得体会

  • 第二题模拟用户操作则有较大难度,尤其是iframe内嵌页面的设置,如果不了解是无法定位到目标然后自动输入的,而且mooc的标签深度很深很长,用xpath工具看起来很累,还是要学会利用属性进行定位,更加简洁美观
    同时mooc页面的标签内存在不断变化的id字段,如果用xpath扩展工具定位的话需要删除id字段。

作业三

  • 要求
    理解Flume架构和关键特性,掌握使用Flume完成日志采集任务。
    完成Flume日志采集实验,包含以下步骤
    • 任务一:开通MapReduce服务

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

      • 步骤1 编写Python脚本

        使用Xshell 7连接服务器:

        直接用xftp拖拽文件autodatapython.py至/opt/client/目录

      • 步骤2 创建目录
        使用mkdir命令在/tmp下创建目录flume_spooldir,我们把Python脚本模拟生成的数据放到此目录下,后面Flume就监控这个文件下的目录,以读取数据。
        mkdir /tmp/flume_spooldir/

      • 步骤3 测试执行
        执行Python命令,测试生成100条数据
        python autodatapython.py "/tmp/flume_spooldir/test.txt" 100

        查看数据:more /tmp/flume_spooldir/test.txt
        more /tmp/flume_spooldir/test.txt

    • 任务三:配置Kafka
      首先设置环境变量,执行source命令,使变量生效

      • 步骤4 在kafka中创建topic(注意更换为自己Zookeeper的ip,端口号一般不动)
        执行如下命令创建topic,替换实际Zookeeper的IP
        /opt/client/Kafka/kafka/bin/kafka-topics.sh --create --zookeeper 192.168.0.225:2181/kafka --partitions 1 --replication-factor 1 --topic fludesc
      • 步骤5 查看topic信息
        /opt/client/Kafka/kafka/bin/kafka-topics.sh --list --zookeeper 192.168.0.225:2181/kafka
    • 任务四:安装Flume客户端

      • 步骤1 打开flume服务界面
        进入MRS Manager集群管理界面,打开服务管理,点击flume,进入Flume服务
      • 步骤2 点击下载客户端


        下载完成后会有弹出框提示下载到哪一台服务器上(这台机器就是Master节点),路径就是/tmp/MRS-client
      • 步骤3 解压下载的flume客户端文件
        使用Xshell7登录到上步中的弹性服务器上,进入/tmp/MRS-client目录

        执行以下命令,解压压缩包获取校验文件与客户端配置包
        tar -xvf MRS_Flume_Client.tar
      • 步骤4 校验文件包
        执行命令:
        sha256sum -c MRS_Flume_ClientConfig.tar.sha256
      • 步骤5 解压“MRS_Flume_ClientConfig.tar”文件
        tar -xvf MRS_Flume_ClientConfig.tar
      • 步骤6 安装Flume环境变量
        执行以下命令,安装客户端运行环境到新的目录“/opt/Flumeenv”,安装时自动生成目录。
        sh /tmp/MRS-client/MRS_Flume_ClientConfig/install.sh /opt/Flumeenv
        查看安装输出信息,如有以下结果表示客户端运行环境安装成功:
        Components client installation is complete

        配置环境变量,执行命令:
        source /opt/Flumeenv/bigdata_env
      • 步骤7 解压Flume客户端
        执行命令:
        cd /tmp/MRS-client/MRS_Flume_ClientConfig/Flume
        tar -xvf FusionInsight-Flume-1.6.0.tar.gz
      • 步骤8 安装Flume客户端
        安装Flume到新目录”/opt/FlumeClient”,安装时自动生成目录。
        执行命令:
        sh /tmp/MRS-client/MRS_Flume_ClientConfig/Flume/install.sh -d /opt/FlumeClient
      • 步骤9 重启Flume服务
        执行一下命令:
        cd /opt/FlumeClient/fusioninsight-flume-1.6.0
        sh bin/flume-manage.sh restart
    • 任务五:配置Flume采集数据

      • 步骤1 修改配置文件(注意更换为自己Kafka的ip,端口号一般不动)
        进入Flume安装目录

        在conf目录下编辑文件properties.properties

         client.sources = s1 
         client.channels = c1 
         client.sinks = sh1 
        
         # the source configuration of s1
         client.sources.s1.type = spooldir
         client.sources.s1.spoolDir = /tmp/flume_spooldir
         client.sources.s1.fileSuffix = .COMPLETED
         client.sources.s1.deletePolicy = never
         client.sources.s1.trackerDir = .flumespool
         client.sources.s1.ignorePattern = ^$
         client.sources.s1.batchSize = 1000
         client.sources.s1.inputCharset = UTF-8
         client.sources.s1.deserializer = LINE
         client.sources.s1.selector.type = replicating
         client.sources.s1.fileHeaderKey = file
         client.sources.s1.fileHeader = false
         client.sources.s1.basenameHeader = true
         client.sources.s1.basenameHeaderKey = basename
         client.sources.s1.deserializer.maxBatchLine = 1
         client.sources.s1.deserializer.maxLineLength = 2048
         client.sources.s1.channels = c1
        
         # the channel configuration of c1
         client.channels.c1.type = memory
         client.channels.c1.capacity = 10000
         client.channels.c1.transactionCapacity = 1000
         client.channels.c1.channlefullcount = 10
         client.channels.c1.keep-alive = 3
         client.channels.c1.byteCapacityBufferPercentage = 20
        
         # the sink configuration of sh1
         client.sinks.sh1.type = org.apache.flume.sink.kafka.KafkaSink
         client.sinks.sh1.kafka.topic = fludesc
         client.sinks.sh1.flumeBatchSize = 1000
         client.sinks.sh1.kafka.producer.type = sync
         client.sinks.sh1.kafka.bootstrap.servers = 192.168.0.152:9092
         client.sinks.sh1.kafka.security.protocol  = PLAINTEXT
         client.sinks.sh1.requiredAcks = 0
         client.sinks.sh1.channel = c1
        
        

        其中client.sinks.sh1.kafka.topic 的值为kafka中创建的topic的值;client.sinks.sh1.kafka.bootstrap.servers的值为Kafka实例Broker的IP和端口

      • 步骤2 创建消费者消费kafka中的数据
        记得改完配置文件要用source命令使其生效。
        登录Master节点,Source幻觉变量后,然后执行命令:
        /opt/client/Kafka/kafka/bin/kafka-console-consumer.sh --topic fludesc --bootstrap-server 192.168.0.152:9092 --new-consumer --consumer.config /opt/client/Kafka/kafka/config/consumer.properties
        注:此处bootstrap-server的ip对应的是Kafka的Broker的IP。
        执行完毕后,在新开一个Xshell 7窗口(右键相应会话-->在右选项卡组中打开),执行2.2.1步骤三的Python脚本命令,再生成一份数据,查看Kafka中是否有数据产生,可以看到,已经消费出数据了:
        有数据产生,表明Flume到Kafka目前是打通的。测试完毕可以关闭Kafka的消费者窗口了

心得体会

  • 作业3给的实验文档很详细,按步骤来没有出现任何问题,但是该实验的知识和目的等还不是很了解,需要后续跟进一下

posted on 2021-11-27 18:07  linzeX  阅读(17)  评论(0编辑  收藏  举报

导航