第五次实验

作业①

要求:

熟练掌握 Selenium 查找HTML元素、爬取Ajax网页数据、等待HTML元素等内容。

使用Selenium框架爬取京东商城某类商品信息及图片。

候选网站

http://www.jd.com/)

输出信息:

MySQL数据库存储和输出格式如下:

代码复现

from selenium import webdriver
from selenium.webdriver.chrome.options import Options
import urllib.request
import threading
import sqlite3
import os
import datetime
from selenium.webdriver.common.keys import Keys
import time
class JD:
    header = {
        "User-Agent": "Mozilla/5.0(Windows;U;Windows NT 6.0 x64;en-US;rv:1.9pre)Gecko/2008072531 Minefield/3.0.2pre"
    }
    # 图片存储的位置
    imagepath = "download"

    def startUp(self, url, key):
        chrome_options = Options()
        chrome_options.add_argument("——headless")
        chrome_options.add_argument("——disable-gpu")
        self.driver = webdriver.Chrome(chrome_options=chrome_options)
        self.threads = []
        self.No = 0
        self.imgNo = 0
        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:
            if not os.path.exists(JD.imagepath):
                os.mkdir(JD.imagepath)
            images = os.listdir(JD.imagepath)
            for image in images:
                s = os.path.join(JD.imagepath, image)
                os.remove(s)
        except Exception as err:
            print(err)
        self.driver.get(url)
        keyinput = self.driver.find_element_by_id("key")
        keyinput.send_keys(key)
        keyinput.send_keys(Keys.ENTER)

    def closeUp(self):
        try:
            self.con.commit()
            self.con.close()
            self.driver.close()
        except Exception as err:
            print(err)

    def insertDB(self, mNo, mMark, mPrice, mNote, mFile):
        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)

    def showDB(self):
        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)

    def downloadDB(self, src1, src2, mFile):
        data = None
        if src1:
            try:
                req = urllib.request.Request(src1, headers=JD.header)
                resp = urllib.request.urlopen(req, timeout=100)
                data = resp.read()
            except:
                pass
        if not data and src2:
            try:
                req = urllib.request.Request(src2, headers=JD.header)
                resp = urllib.request.urlopen(req, timeout=100)
                data = resp.read()
            except:
                pass
        if data:
            print("download begin!", mFile)
            fobj = open(JD.imagepath + "\\" + mFile, "wb")
            fobj.write(data)
            fobj.close()
            print("download finish!", mFile)

    def processJD(self):
        time.sleep(10)
        try:
            print(self.driver.current_url)
            lis = self.driver.find_elements_by_xpath("//div[@id='J_goodsList']//li[@class='gl-item']")
            time.sleep(1)
            for li in lis:
                time.sleep(1)
                try:
                    src1 = li.find_element_by_xpath(".//div[@class='p-img']//a//img").get_attribute("src")
                    time.sleep(1)
                except:
                    src1 = ""
                try:
                    src2 = li.find_element_by_xpath(".//div[@class='p-img']//a//img").get_attribute("data-lazy-img")
                    time.sleep(1)
                except:
                    src2 = ""
                try:
                    price = li.find_element_by_xpath(".//div[@class='p-price']//i").text
                    time.sleep(1)
                except:
                    price = "0"

                note = li.find_element_by_xpath(".//div[@class='p-name p-name-type-2']//em").text
                mark = note.split(" ")[0]
                mark = mark.replace("爱心东东\n", "")
                mark = mark.replace(",", "")
                note = note.replace("爱心东东\n", "")
                note = note.replace(",", "")
                time.sleep(1)
                self.No = self.No + 1
                no = str(self.No)
                while len(no) < 6:
                    no = "0" + no
                print(no, mark, price)
                if src1:
                    src1 = urllib.request.urljoin(self.driver.current_url, src1)
                    p = src1.rfind(".")
                    mFile = no + src1[p:]
                elif src2:
                    src2 = urllib.request.urljoin(self.driver.current_url, src2)
                    p = src2.rfind(".")
                    mFile = no + src2[p:]
                if src1 or src2:
                    T = threading.Thread(target=self.downloadDB, args=(src1, src2, mFile))
                    T.setDaemon(False)
                    T.start()
                    self.threads.append(T)
                else:
                    mFile = ""
                self.insertDB(no, mark, price, note, mFile)

        except Exception as err:
            print(err)
    def executeJD(self, url, key):
        starttime = datetime.datetime.now()
        print("starting!")
        self.startUp(url, key)
        print("processing!")
        self.processJD()
        print("closing!")
        self.closeUp()
        for t in self.threads:
            t.join()
        print("complete!")
        endtime = datetime.datetime.now()
        elapsed = (endtime - starttime).seconds
        print("Total", elapsed, "seconds elasped")
url = "https://www.jd.com"
spider = JD()
while True:
    print("1.爬取")
    print("2.显示")
    print("3.退出")
    s = input("请选择(1,2,3);")
    if s == "1":
        JD().executeJD(url, '手机')
        continue
    elif s == "2":
        JD().showDB()
        continue
    elif s == "3":
        break

运行结果:

Gitee地址:

作业一:
https://gitee.com/flyme10086/data-excavate/blob/master/作业5/jd_chrome.py

心得体会:

此实验通过对书本代码的复现,使我们进一步了解selenium和xpath的使用及通过MySQL数据库储存数据。

作业②

要求:

熟练掌握 Selenium 查找HTML元素、实现用户模拟登录、爬取Ajax网页数据、等待

HTML元素等内容。

使用Selenium框架+MySQL爬取中国mooc网课程资源信息(课程号、课程名称、教学

进度、课程状态,课程图片地址),同时存储图片到本地项目根目录下的imgs文件夹
中,图片的名称用课程名来存储。

候选网站:

中国mooc网:https://www.icourse163.org

输出信息:

表头应是英文命名例如:课程号ID,课程名称:cCourse……,由同学们自行定义

设计表头:

设置启动chrome时可见,便于发现错误原因

driver = webdriver.Chrome()

初始界面

driver.get("https://www.icourse163.org")

数据库操作

#打开数据库连接
conn = pymysql.connect(host="localhost",user="root",passwd="278676",port=3306,charset="utf8")
# #获取游标
cursor = conn.cursor()
#创建moocdb数据库
cursor.execute('CREATE DATABASE IF NOT EXISTS moocdb DEFAULT CHARSET utf8 COLLATE utf8_general_ci;')
#选择数据库
conn.select_db('moocdb')
#获取游标
cursor = conn.cursor()
#创建表icourse
cursor.execute('drop table if exists icourse')
sql="""CREATE TABLE IF NOT EXISTS `icourse` (
	  `ID` varchar(16) NOT NULL,
	  `cCourse` varchar(255) NOT NULL,
	  `cCollege` varchar(255),
	  `cSchedule` varchar(255),
	  `cCourseStatus` varchar(255),
	  `cImgUrl` varchar(255),
	  PRIMARY KEY (`cCourse`)
	) ENGINE=InnoDB  DEFAULT CHARSET=utf8"""
cursor.execute(sql)

进行模拟登录

# 点击登录按钮
login = driver.find_element(By.XPATH,'//*[@id="j-topnav"]')
login.click()
time.sleep(10) #留出扫码的时间
# 点击我的课程
mycourse = driver.find_element(By.XPATH,'//*[@id="j-indexNav-bar"]/div/div/div/div/div[7]/div[3]/div')
mycourse.click()

获取网页数据

course = driver.find_elements(By.XPATH,'//*[@id="j-coursewrap"]/div/div[1]/div/div/a/div[2]/div/div/div/span[@class="text"]')
college = driver.find_elements(By.XPATH,'//*[@id="j-coursewrap"]/div/div[1]/div/div/a/div[2]/div/div[@class="school"]/a')
schedule = driver.find_elements(By.XPATH,'//*[@id="j-coursewrap"]/div/div[1]/div/div[1]/a/div[2]/div[2]/div[1]/div[1]/div[1]/a/span')
status = driver.find_elements(By.XPATH,'//*[@id="j-coursewrap"]/div/div[1]/div/div[1]/a/div[2]/div[2]/div[2]')
imgurl = driver.find_elements(By.XPATH,'//*[@id="j-coursewrap"]/div/div[1]/div/div[1]/a/div[1]/img')

将图片保存并将数据插入数据库

for i in range(len(course)):
    response = urllib.request.urlopen(imgurl[i].get_attribute("src"))
    img = response.read()
    imgname = './imgs/' + course[i].text + '.jpg'
    with open(imgname, 'wb') as f:
        f.write(img)
    print("第", i+1, "张图片爬取完成;")
    cursor.execute("insert into icourse (ID,cCourse,cCollege,cSchedule,cCourseStatus,cImgUrl) values (%s,%s,%s,%s,%s,%s)",
                   (str(i+1),course[i].text, college[i].text, schedule[i].text, status[i].text, imgurl[i].get_attribute("src")))
    print(str(i+1),course[i].text, college[i].text, schedule[i].text, status[i].text, imgurl[i].get_attribute("src"))

上传并关闭数据库

#上传数据
conn.commit()
#先关闭游标
cursor.close()
#再关闭数据库连接
conn.close()

运行结果:


Gitee地址:

作业二:
https://gitee.com/flyme10086/data-excavate/blob/master/作业5/icourse_chrome.py

心得体会:

本次作业通过使用selenium+xpath+MySQL数据库储存技术,使我进一步掌握了selenium框架的使用,并对MYSQL数据库的增删改查有了更进一步的了解。

遇到的问题:

模拟登录本来打算使用账号密码进行登录,在实现的过程中遇到了较为困难的验证机制,超出目前的能力范围。故采用较为简单的扫码登录。

作业③

要求:

理解Flume架构和关键特性,掌握使用Flume完成日志采集任务。

完成Flume日志采集实验,包含以下步骤:

任务一:开通MapReduce服务(略)

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

1、使用Xshell 7连接服务器,进入/opt/client/目录,用xftp7将本地的autodatapython.py文件上传至服务器/opt/client/目录下。
2、创建目录,使用mkdir命令在/tmp下创建目录flume_spooldir,我们把Python脚本模拟生成的数据放到此目录下,后面Flume就监控这个文件下的目录,以读取数据。
3、测试执行,执行Python命令,测试生成100条数据,查看数据。

运行结果:

任务三:配置Kafka

1、设置环境变量,执行source命令,使变量生效
2、在kafka中创建topic
3、查看topic信息

运行结果:

任务四:安装Flume客户端

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

运行结果:


2、解压下载的flume客户端文件。使用Xshell7登录到上步中的弹性服务器上,进入/tmp/MRS-client目录,解压压缩包获取校验文件与客户端配置包,校验文件包,解压“MRS_Flume_ClientConfig.tar”文件。

运行结果:


3、安装客户端运行环境到新的目录“/opt/Flumeenv”,安装时自动生成目录。查看安装输出信息,如有以下结果表示客户端运行环境安装成功:

4、配置环境变量,解压Flume客户端

运行结果:


5、安装Flume到新目录”/opt/FlumeClient”,安装时自动生成目录。

运行结果:

任务五:配置Flume采集数据

1、修改配置文件,创建消费者消费kafka中的数据。执行完毕后,在新开一个Xshell 7窗口(右键相应会话-->在右选项卡组中打开),执行2.2.1步骤三的Python脚本命令,再生成一份数据,查看Kafka中是否有数据产生,可以看到,已经消费出数据了:

心得体会:

本次作业主要介绍如何使用Flume进行实时流前端数据采集,方便为之后数据处理和数据的可视化,是实时流场景数据流通的部分工作,通过本次实验的学习,使我能够掌握实时场景下,大数据的数据采集能力。

posted @ 2021-11-24 17:28  Flyme10086  阅读(37)  评论(0编辑  收藏  举报