数据采集与融合技术_实践5
作业①:
要求:
熟练掌握 Selenium 查找HTML元素、爬取Ajax网页数据、等待HTML元素等内容。
使用Selenium框架爬取京东商城某类商品信息及图片。
候选网站:http://www.jd.com/
关键词:学生自由选择
1.1 实验过程
1.1.1 模拟用户搜索商品关键词
- 在京东的主页面上对搜索栏点击右键进行检查,通过 find_element_by_id("key") 进行定位,
模拟用户填写搜索关键词并回车进入相关页面。

self.driver.get(url) #JD首页
keyInput = self.driver.find_element_by_id("key") #寻找搜索栏
keyInput.send_keys(key)#将关键词手机输入
keyInput.send_keys(Keys.ENTER) #模拟回车
send_keys 的一些用法:剪切粘贴全选等操作与复制相似,修改为对应字母即可。
语法 | 效果 |
---|---|
send_keys(Keys.BACK_SPACE) | 删除键BackSpace |
send_keys(Keys.SPACE) | 空格键Space |
send_keys(Keys.ENTER) | 回车键Enter |
send_keys(Keys.CONTROL,‘c’) | 复制CTRL+C |
1.1.2 爬取商品信息
- 关于 mMark 的获取:
观察发现,标题的第一个单词即为手机的品牌,所以我们需要对标题进行分割。
但是要注意有些手机品牌前面会存在“京品手机”的标签,我们需要将其删除。

- 通过空格进行切割后可以发现,京品手机是和品牌连在一起的,所以可得代码如下:
note = li.find_element_by_xpath(".//div[@class='p-name p-name-type-2']//em").text
mark = note.split(" ")[0]
if(mark[0:4] == '京品手机'): #去除不必要的信息
mark = mark[4:]
- 关于图片src的获取:
需要分以下两种情况
Xpath路径 |
---|
li.find_element_by_xpath(".//div[@class='p-img']//a//img").get_attribute("src") |
li.find_element_by_xpath(".//div[@class='p-img']//a//img").get_attribute("data-lazy-img") |
我比较疑惑的是属性 data-lazy-img,因为直接查看网页html或使用xpath helper时,这个属性的值都是done,并且图片的地址都是在 src 属性中。
查询相关资料发现,我所看到的html是经过响应的,使用python获取源码就可以明白其中缘由。

- 其他信息正常获取即可,根据需要可以做一些处理,这里就不再展示。
1.1.3 商品加载
- 可以发现,页面下拉前每页只有 30 件商品

- 然而,页面下拉后每页共有 60 件商品

- 因此如果要获取完整信息,需要使用模拟下拉的方式加载更多的商品。
而滚动条是无法直接定位的。selenium中也没有直接的方法来控制滚动条,我们可以用Js处理。
#控制页面下拉
js = 'document.documentElement.scrollTop=10000' #10000代表底部
self.driver.execute_script(js)
time.sleep(5) #需要停止一段时间,让页面加载
1.1.4 翻页处理
- 限制爬取的数量为101,由于每页有60件商品,所以只会爬到第二页。
if(self.No < 101): #限定爬取101个
try:
nextPage = self.driver.find_element_by_xpath("//span[@class='p-num']//a[@class='pn-next']")
time.sleep(5)
nextPage.click()
self.processSpider() #爬取新的一页
except Exception as err:
print(err)
1.1.5 下载图片
- urllib请求访问资源,获取图片数据,注意一下传过来的src1和src2是 相对地址,需要先使用urljoin进行补全,才能正确访问。
成功下载后,保存到本地文件夹。
#urllib请求
req = urllib.request.Request(src1, headers=MySpider.headers)
resp = urllib.request.urlopen(req, timeout=10)
data = resp.read()
...
if data: #成功获取图片数据后才需要写入
fobj = open(MySpider.imagePath + "\\" + mFile, "wb")
fobj.write(data)
fobj.close()
1.1.6 数据库
- 建表
def openDB(self):
print("opened")
try:
#数据库连接
self.con = pymysql.connect(host="localhost", port=3306, user="root",
passwd="cccc", db="crawl", charset="utf8")
self.cursor = self.con.cursor(pymysql.cursors.DictCursor)
#创建表
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 Exception as err:
self.cursor.execute("delete from phones")
- 插入
def insert(self,mNo, mMark, mPrice, mNote, mFile):
#if self.opened:
sql = "insert into phones (mNo,mMark,mPrice,mNote,mFile) values ( % s, % s, % s, % s, % s)"
self.cursor.execute(sql, (mNo, mMark, mPrice, mNote, mFile))
1.1.7 运行结果
- 数据库存储

- 下载的图片

1.2 实验心得
- 本题主要是利用Selenium模拟爬取京东的商品存入数据库,并下载相关图片。
新学了通过执行js脚本进行页面下拉的方式,但是要记得sleep一段时间让页面加载。强化相对地址绝对地址的意识,要多多注意。
代码链接
https://gitee.com/yozhibo/crawl_project/blob/master/task_5/job_1
作业②:
要求:
熟练掌握 Selenium 查找HTML元素、实现用户模拟登录、爬取Ajax网页数据、等待HTML元素等内容。
使用Selenium框架+MySQL模拟登录慕课网,并获取学生自己账户中已学课程的信息保存到MySQL中(课程号、课程名称、授课单位、教学进度、课程状态,课程图片地址),同时存储图片到本地项目根目录下的imgs文件夹中,图片的名称用课程名来存储。
候选网站:中国mooc网:https://www.icourse163.org
2.1 实验过程
2.1.1 模拟登陆
- 两种登录方法
一是手机号登录,需要模拟更多的点击和输入,而且会遇到嵌套页面的问题,但完成后不需要每次运行都扫码。
二是扫码登陆,需要设定几秒的等待时间,用手机app扫码登录。

- 手机号登录:
① 模拟点击“登录”、“其他方式登录” 和 “手机号登录”
#登录入口
wait.until(EC.element_to_be_clickable(
(By.XPATH, '//*[@id="app"]/div/div/div[1]/div[3]/div[3]/div'))).click()
#其他登录方式
wait.until(EC.element_to_be_clickable(
(By.XPATH, '//div[@class="mooc-login-set"]//span[@class="ux-login-set-scan-code_ft_back"]'))).click()
#手机号登录
wait.until(EC.element_to_be_clickable(
(By.XPATH, '//ul[@class="ux-tabs-underline_hd"]/li[position()=2]'))).click()
② 找到 iframe 并进行定位,并切换定位器到 iframe

#寻找嵌套的页面
iframe = self.driver.find_element_by_xpath('//div[@id="j-ursContainer-1"]/iframe[1]')
self.driver.switch_to.frame(iframe)
②模拟输入账户、密码,点击登录
#账号密码
PHONENUM= "101" #在101行,可自行修改。
PASSWORD = "102"
#输入账户
self.driver.find_element_by_xpath\
('//div[@class="u-input box"]//input[@type="tel"]').send_keys(PHONENUM)
#输入密码
self.driver.find_element_by_xpath\
('//div[@class="inputbox"]//input[@type="password"][2]').send_keys(PASSWORD)
#点击登录按钮
self.driver.find_element_by_xpath('//*[@id="submitBtn"]').click()
- 扫码登录:
wait = WebDriverWait(self.driver, 8)
#登录入口
wait.until(EC.element_to_be_clickable(
(By.XPATH, '//*[@id="app"]/div/div/div[1]/div[3]/div[3]/div'))).click()
#等待5秒,加上下一步会有 wait 8秒,扫码时间还是比较充裕的
time.sleep(5)
2.1.2 课程信息爬取
- 首先要进入 “个人中心” 页面

#点击个人中心
wait.until(EC.element_to_be_clickable(
(By.XPATH,'//*[@id="j-indexNav-bar"]/div/div/div/div/div[7]/div[3]/div/div/a/span'))).click()
进入后可以查看各门课程:课程信息在如图框出来的部分,共6门。
- 课程信息的爬取比较常规,这里直接展示主要代码
Id = self.No #序号
cCourse = li.find_element_by_xpath('.//span[@class="text"]').text #课程名
cCollege = li.find_element_by_xpath('.//div[@class="school"]').text #开课大学
cSchedule = li.find_element_by_xpath('.//span[@class="course-progress-text-span"]').text #课程进度
cCourseStatus = li.find_element_by_xpath('.//div[@class="course-status"]').text #课程状态
cImgUrl = li.find_element_by_xpath('.//div[@class="img"]/img').get_attribute("src") #课程图
self.No += 1
2.1.3 数据库show()函数
- 将爬取到的课程信息输出到控制台
for row in rows:
print("%-10s %-20s %-20s %-20s %-30s %-30s" % (row['Id'], row['cCourse'],
row['cSchedule'], row['cSchedule'], row['cCourseStatus'],row['cImgUrl']))
2.1.4 图片下载
- 用课程名命名图片,要注意补上图片的格式。
p = cImgUrl.rfind(".") #确定图片后缀名位置
cCourse = cCourse + cImgUrl[p:p+4] #将图片的后缀名加到课程名后
T = threading.Thread(target=self.download, args=(cImgUrl, cCourse)) #多线程下载
2.1.5 结果展示
- 数据库存储

- 数据库输出
- 图片下载

2.2 实验心得
- 除了因为渲染而无法正确定位外,还有可能是因为进行了页面嵌套。
扫码登录时让我对selenium有了更深的体会,它是用程序去模拟人的操作,
而在这期间人也是可以有自己的操作,两者结合可以相互弥补缺陷。
代码链接
- 代码运行前需要 修改账号密码(位于101行和102行)
https://gitee.com/yozhibo/crawl_project/blob/master/task_5/job_2#
作业③:Flume日志采集实验
要求:掌握大数据相关服务,熟悉Xshell的使用
完成文档 华为云_大数据实时分析处理实验手册-Flume日志采集实验(部分)v2.docx 中的任务,即为下面5个任务,具体操作见文档。
任务一:开通MapReduce服务(环境搭建)

任务二:Python脚本生成测试数据
- 将本地的autodatapython.py文件上传至服务器/opt/client/目录下

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

任务三:配置Kafka
- source环境变量

- 在kafka中创建topic

- 查看topic信息

任务四:安装Flume客户端
- 解压安装包

- 安装Flume客户端

- 重启Flume服务

任务五:配置Flume采集数据
- 修改配置文件后,用Xshell上传到服务器

- 创建消费者消费kafka中的数据

- 新开Xshell 7窗口,执行Python脚本命令

实验心得
- 大体上还是跟着实验步骤走,比较流畅。学会了在华为云平台上进行资源申请和释放,特别是mapreduce服务,同时也初步掌握了flume日志采集的步骤。