「数据采集」实验五


作业①

  • 要求:

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

  • 候选网站:http://www.jd.com/
  • 关键词:学生自由选择
  • 输出信息:
mNo mMark mPrice mNote mFile
000001 三星Galaxy 9199.00 三星Galaxy Note20 Ultra 5G...
000002 ... ... ... ...

Gitee链接:作业5_1

1、网页解析

  • 搜索框

keyInput = self.driver.find_element(By.ID,"key")

  • 商品列表

lis = self.driver.find_elements(By.XPATH,"//div[@id='J_goodsList']//li[@class='gl-item']")

  • 商品信息

src1 = li.find_element(By.XPATH,".//div[@class='p-img']//a//img").get_attribute("src")
src2 = li.find_element(By.XPATH,".//div[@class='p-img']//a//img").get_attribute("data-lazy-img")
price = li.find_element(By.XPATH,".//div[@class='p-price']//i").text
note = li.find_element(By.XPATH,".//div[@class='p-name p-name-type-2']//em").text

  • 翻页

    nextPage = self.driver.find_element(By.XPATH,"//span[@class='p-num']//a[@class='pn-next']")

2、配置信息

chrome_options = Options()
chrome_options.add_argument('--headless')
chrome_options.add_argument('--disable-gpu')
self.driver = webdriver.Chrome(chrome_options=chrome_options)

3、数据库操作

# 创建表
try:
   self.con = sqlite3.connect("phones.db")
   self.cursor = self.con.cursor()
   try:
       # 如果有表就删除
       self.cursor.execute("drop table phones")
   except:
       pass
   try:
        #  建立新的表
        sql = "create  table  phones  (mNo  varchar(32) primary key, mMark varchar(256),mPrice varchar(32),mNote varchar(1024),mFile varchar(256))"
        self.cursor.execute(sql)
   except:
        pass
except Exception as err:
    print(err)

# 插入数据
try:
    sql = "insert into phones (mNo,mMark,mPrice,mNote,mFile) values (?,?,?,?,?)"
    self.cursor.execute(sql, (mNo, mMark, mPrice, mNote, mFile))
except Exception as err:
    print(err)

# 输出内容
try:
    con = sqlite3.connect("phones.db")
    cursor =con.cursor()
    print("%-8s%-16s%-8s%-16s%s"%("No", "Mark", "Price", "Image", "Note"))
    cursor.execute("select mNo,mMark,mPrice,mFile,mNote from phones  order by mNo")

    rows = cursor.fetchall()
    for row in rows:
        print("%-8s %-16s %-8s %-16s %s" % (row[0], row[1], row[2], row[3],row[4]))

    con.close()
except Exception as err:
    print(err)

4、保存图片

# 创建文件夹
try:
     if not os.path.exists(MySpider.imagePath):
           os.mkdir(MySpider.imagePath)
     images = os.listdir(MySpider.imagePath)
     for img in images:
           s = os.path.join(MySpider.imagePath, img)
           os.remove(s)
except Exception as err:
     print(err)

# 保存
data = None
if src1:
     try:
         req = urllib.request.Request(src1, headers=MySpider.headers)
         resp = urllib.request.urlopen(req, timeout=10)
         data = resp.read()
      except:
          pass
if not data and src2:
      try:
          req = urllib.request.Request(src2, headers=MySpider.headers)
          resp = urllib.request.urlopen(req, timeout=10)
          data = resp.read()
      except:
          pass
if data:
      print("download begin", mFile)
      fobj = open(MySpider.imagePath + "\\" + mFile, "wb")
      fobj.write(data)
      fobj.close()
      print("download finish", mFile)

5、运行结果

  • 控制台输出
  • 数据库截图
  • 本地文件夹截图

6、心得体会

  • 数据库操作不断出现database is locked的报错,目前的解决方法是设置databasenot alive,再重新设置为Alive,比较麻烦;
  • 通过复现进一步熟悉了Selenium框架,Selenium 查找HTML元素、爬取Ajax网页数据、等待HTML元素等内容。

作业②

  • 要求:
    • 熟练掌握 Selenium 查找HTML元素、实现用户模拟登录、爬取Ajax网页数据、等待HTML元素等内容。
    • 使用Selenium框架+MySQL爬取中国mooc网课程资源信息(课程号、课程名称、教学进度、课程状态,课程图片地址),同时存储图片到本地项目根目录下的imgs文件夹中,图片的名称用课程名来存储。
  • 候选网站:中国mooc网:https://www.icourse163.org
  • 输出信息:
Id cCourse cCollege cSchedule cCourseStatus cImgUrl
1 Python网络爬虫与信息提取 北京理工大学 已学3/18课时 2021年5月18日已结束 http://edu-image.nosdn.127.net/C0AB6FA791150F0DFC0946B9A01C8CB2.jpg2......

Gitee链接:作业5_2

1、网页解析

  • 登录

    driver.find_element(By.XPATH,'//div[@class="u-navLogin-loginBox"]//div[@class="unlogin"]/a').click()
  • 个人中心

    driver.find_element(By.XPATH, '//div[@class="u-navLogin-myCourse-t"]//span[@class="nav"]').click()
  • 课程列表

    divs = driver.find_elements(By.XPATH,'//div[@class="course-panel-body-wrapper"]/div[@class="course-card-wrapper"]')
  • 课程信息
# 获取课程名称
course = div.find_element(By.XPATH,'.//div[@class="title"]//span[@class="text"]').text
# 获取院校
college = div.find_element(By.XPATH,'.//div[@class="school"]/a').text
# 获得已学学时
schedule = div.find_element(By.XPATH,'.//div[@class="status"]//span[@class="course-progress-text-span"]').text
# 获取课程开设时间
courseStatus = div.find_element(By.XPATH,'.//div[@class="course-status"]').text

2、登录函数 login()

def login():
    # 请求网站
    driver.get('https://www.icourse163.org/')
    # 改变窗口宽度,不要最大化,会被反爬虫检测到
    driver.set_window_size(1300, 800)
    # 点击二维码扫描
    driver.find_element(By.XPATH,'//div[@class="u-navLogin-loginBox"]//div[@class="unlogin"]/a').click()
    # 等待扫描二维码
    time.sleep(10)

3、搜索函数 to_searchs()

def to_searchs(page):
    # 点击个人中心
    driver.find_element(By.XPATH, '//div[@class="u-navLogin-myCourse-t"]//span[@class="nav"]').click()
    # driver.execute_script("arguments[0].click();", search)
    for i in range(page):
        # 拉动侧边滑动条,使页面数据加载完全
        drop_scroll()
        # 获取课程信息
        get_courses()
        # 获取下一页框
        nextPage = driver.find_element(By.XPATH,'//li[@class="ux-pager_btn ux-pager_btn__next"]/a')
        driver.execute_script("arguments[0].click();", nextPage)

4、获取信息函数 getCourses()

def get_courses():
    # 序号
    global count
    # 分析页面后,获取div里面的数据
    divs = driver.find_elements(By.XPATH,//div[@class="course-panel-body-wrapper"]/div[@class="course-card-wrapper"]')
    # 遍历每个divs,获取详细信息
    for div in divs:
        count += 1
        # 获取课程名称
        course = div.find_element(By.XPATH,'.//div[@class="title"]//span[@class="text"]').text
        # 获取院校
        college = div.find_element(By.XPATH,'.//div[@class="school"]/a').text
        # 获得已学学时
        schedule = div.find_element(By.XPATH,'.//div[@class="status"]//span[@class="course-progress-text-span"]').text
        # 获取课程开设时间
        courseStatus = div.find_element(By.XPATH,'.//div[@class="course-status"]').text
        # 获取图片地址
        src_path = div.find_element(By.XPATH,'.//div[@class="img"]/img').get_attribute('src')
        # 请求图片地址,并进行下载
        try:
            response = requests.get(src_path)
            file_path = './MOOC/' + course + '.jpg'
            with open(file_path, 'wb') as f:  # 图片信息是二进制形式,所以要用wb写入
                f.write(response.content)
                print('success ' + str(count) + '.jpg')
        except Exception as err:
            print(err)
        print(count,course,college,schedule,courseStatus,src_path)
        # 向数据库添加一条数据
        db.insert(count,course,college,schedule,courseStatus,src_path)
        print(str(count) + 'inserted')

5、运行结果

  • 控制台输出
  • 数据库截图
  • 本地文件夹

6、心得体会

  • 进一步熟悉了Selenium框架,Selenium 查找HTML元素、爬取Ajax网页数据、等待HTML元素等内容。

作业③

  • 要求:理解Flume架构和关键特性,掌握使用Flume完成日志采集任务。
  • 完成Flume日志采集实验,包含以下步骤:
    1、任务一:开通MapReduce服务
    2、任务二:Python脚本生成测试数据
    3、任务三:配置Kafka
    4、任务四:安装Flume客户端
    5、任务五:配置Flume采集数据

1、开通MapReduce服务

2、Python脚本生成测试数据

  • 使用Xshell7 连接服务器

  • 进入/opt/client/目录,使用 vi 命令编写 Python 脚本:vi autodatapython.py(这里直接用xftp7 将本地的 autodatapython.py 文件上传至服务器/opt/client/目录下即可,不必再使用vi/vim 命令,以免出错,难以修改)
  • 使用 mkdir 命令在/tmp 下创建目录 flume_spooldir,我们把 Python 脚本模拟生成的数据放到此目录下,后面 Flume 就监控这个文件下的目录,以读取数据。
    mkdir /tmp/flume_spooldir/
  • 执行 Python 命令,测试生成 100 条数据
    python autodatapython.py "/tmp/flume_spooldir/test.txt" 100
  • 查看数据
    more /tmp/flume_spooldir/test.txt

3、配置Kafka

  • 设置环境变量,执行source命令,使变量生效
    source /opt/client/bigdata_env
  • 在 kafka 中创建 topic(注意更换为自己 Zookeeper 的 ip,端口号一般不动)
    /opt/client/Kafka/kafka/bin/kafka-topics.sh --create --zookeeper 192.168.0.77:2181/kafka --partitions 1 --replication-factor 1 --topic fludesc
  • 查看 topic 信息
    /opt/client/Kafka/kafka/bin/kafka-topics.sh --list --zookeeper 192.168.0.6:2181/kafka

4、安装Flume客户端

  • 打开 flume 服务界面
  • 下载完成后会有弹出框提示下载到哪一台服务器上(这台机器就是 Master 节点),路径就是/tmp/MRS-client:
  • 使用 Xshell7 登录到上步中的弹性服务器上,进入/tmp/MRS-client 目录
  • 执行以下命令,解压压缩包获取校验文件与客户端配置包
    tar -xvf MRS_Flume_Client.tar
  • 校验文件包
    sha256sum -c MRS_Flume_ClientConfig.tar.sha256
    界面显示如下信息,表明文件包校验成功:
  • 解压“MRS_Flume_ClientConfig.tar”文件
    tar -xvf MRS_Flume_ClientConfig.tar
  • 执行以下命令,安装客户端运行环境到新的目录“/opt/Flumeenv”,安装时自动生成目录。
    sh /tmp/MRS-client/MRS_Flume_ClientConfig/install.sh /opt/Flumeenv

    查看安装输出信息,如有以下结果表示客户端运行环境安装成功:
  • 配置环境变量,执行命令:
    source /opt/Flumeenv/bigdata_env
  • 解压 Flume 客户端
    cd /tmp/MRS-client/MRS_Flume_ClientConfig/Flume
    tar -xvf FusionInsight-Flume-1.6.0.tar.gz
  • 安装 Flume 到新目录”/opt/FlumeClient”,安装时自动生成目录。
    sh /tmp/MRS-client/MRS_Flume_ClientConfig/Flume/install.sh -d /opt/FlumeClient
  • 重启 Flume 服务
    cd /opt/FlumeClient/fusioninsight-flume-1.6.0
    sh bin/flume-manage.sh restart
  • 安装结束

5、配置 Flume 采集数据

  • 进入 Flume 安装目录
    cd /opt/FlumeClient/fusioninsight-flume-1.6.0/
  • 在 conf 目录下编辑文件 properties.properties
    其中 client.sinks.sh1.kafka.topic 的值为 kafka 中创建的 topic 的值;client.sinks.sh1.kafka.bootstrap.servers 的值为 Kafka 实例 Broker 的 IP 和端口
  • 创建消费者消费 kafka 中的数据
    /opt/client/Kafka/kafka/bin/kafka-console-consumer.sh --topic fludesc --bootstrap-server 192.168.0.54:9092 --new-consumer --consumer.config /opt/client/Kafka/kafka/config/consumer.properties
    此处 bootstrap-server 的 ip 对应的是 Kafka 的 Broker 的 IP。

    执行完毕后,在新开一个 Xshell 7 窗口(右键相应会话-->在右选项卡组中打开),执行 任务二的 Python 脚本命令,再生成一份数据,查看 Kafka 中是否有数据产生,可以看到,已经消费出数据了:

6、心得体会

  • 了解了如何使用 Flume 进行实时流前端数据采集
    -通过本实验的学习,初步掌握了实时场景下,大数据的数据采集能力。