第五次实验
作业①
要求:
熟练掌握 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中是否有数据产生,可以看到,已经消费出数据了: