数据采集第五次作业

作业一:

(1)实验要求:

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

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

关键词:学生自由选择

输出信息:MYSQL的输出信息如下

mNo mMark  mPrice  mNote  mFile

000001

三星 Galaxy

9199.00

三星Galaxy Note20 Ultra 5G...

000001.jpg
         

    

(2)题目分析:

①首先打开网站源代码,我们要找到搜索框、商品的信息以及所在列表、还有就是控制翻页的按钮:

用来定位搜索框:

用来定位商品列表:

用来定位商品信息,下图分别为图片、价格、名称和简介、翻页:

②代码部分:

  1 from selenium import webdriver
  2 from selenium.webdriver.chrome.options import Options
  3 import urllib.request
  4 import threading
  5 import sqlite3
  6 import os
  7 import datetime
  8 from selenium.webdriver.common.by import By
  9 from selenium.webdriver.common.keys import Keys
 10 import time
 11 
 12 class MySpider:
 13     headers = {
 14         "User-Agent": "SMozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) "
 15                       "Chrome/86.0.4240.183 Safari/537.361 "
 16         }
 17     # 保存图片的文件夹
 18     imagePath = "imgs/dangdang"
 19     def startUp(self, url, key):
 20         # Initializing Chrome browser
 21         chrome_options = Options()
 22         chrome_options.add_argument('--headless')
 23         chrome_options.add_argument('--disable-gpu')
 24         self.driver = webdriver.Chrome()
 25         self.threads = []
 26         self.No = 0
 27         self.imgNo = 0
 28         try:
 29             self.con = sqlite3.connect("phones.db")
 30             self.cursor = self.con.cursor()
 31             try:
 32                 # 如果有表就删除
 33                 self.cursor.execute("drop table phones")
 34             except:
 35                 pass
 36             try:
 37                 #  建立新的表
 38                 sql = "create  table  phones  (mNo  varchar(32) primary key, mMark varchar(256),mPrice varchar(32),mNote varchar(1024),mFile varchar(256))"
 39                 self.cursor.execute(sql)
 40             except:
 41                 pass
 42         except Exception as err:
 43             print(err)
 44             # Initializing images folder
 45         try:
 46             if not os.path.exists(MySpider.imagePath):
 47                 os.mkdir(MySpider.imagePath)
 48             images = os.listdir(MySpider.imagePath)
 49             for img in images:
 50                 s = os.path.join(MySpider.imagePath, img)
 51                 os.remove(s)
 52         except Exception as err:
 53             print(err)
 54         self.driver.get(url)
 55         keyInput = self.driver.find_element(By.ID,"key")
 56         keyInput.send_keys(key)
 57         keyInput.send_keys(Keys.ENTER)
 58 
 59     def closeUp(self):
 60         try:
 61             self.con.commit()
 62             self.con.close()
 63             self.driver.close()
 64         except Exception as err:
 65             print(err)
 66     def insertDB(self, mNo, mMark, mPrice, mNote, mFile):
 67         try:
 68             sql = "insert into phones (mNo,mMark,mPrice,mNote,mFile) values (?,?,?,?,?)"
 69             self.cursor.execute(sql, (mNo, mMark, mPrice, mNote, mFile))
 70         except Exception as err:
 71             print(err)
 72 
 73     def showDB(self):
 74         try:
 75             con = sqlite3.connect("phones.db")
 76             cursor = con.cursor()
 77             print("%-8s%-16s%-8s%-16s%s" % ("No", "Mark", "Price", "Image", "Note"))
 78             cursor.execute("select mNo,mMark,mPrice,mFile,mNote from phones  order by mNo")
 79             rows = cursor.fetchall()
 80             for row in rows:
 81                 print("%-8s %-16s %-8s %-16s %s" % (row[0], row[1], row[2], row[3], row[4]))
 82             con.close()
 83         except Exception as err:
 84             print(err)
 85 
 86     def download(self, src1, src2, mFile):
 87         data = None
 88         if src1:
 89             try:
 90                 req = urllib.request.Request(src1, headers=MySpider.headers)
 91                 resp = urllib.request.urlopen(req, timeout=10)
 92                 data = resp.read()
 93             except:
 94                 pass
 95         if not data and src2:
 96             try:
 97                 req = urllib.request.Request(src2, headers=MySpider.headers)
 98                 resp = urllib.request.urlopen(req, timeout=10)
 99                 data = resp.read()
100             except:
101                 pass
102         if data:
103             print("download begin", mFile)
104             fobj = open(MySpider.imagePath + "\\" + mFile, "wb")
105             fobj.write(data)
106             fobj.close()
107             print("download finish", mFile)
108     def processSpider(self):
109         try:
110             time.sleep(1)
111             print(self.driver.current_url)
112             lis = self.driver.find_elements(By.XPATH,"//div[@id='J_goodsList']//li[@class='gl-item']")
113             for li in lis:
114                 try:
115                     src1 = li.find_element(By.XPATH,".//div[@class='p-img']//a//img").get_attribute("src")
116                 except:
117                     src1 = ""
118                 try:
119                     src2 = li.find_element(By.XPATH,".//div[@class='p-img']//a//img").get_attribute("data-lazy-img")
120                 except:
121                     src2 = ""
122                 try:
123                     price = li.find_element(By.XPATH,".//div[@class='p-price']//i").text
124                 except:
125                     price = "0"
126                 try:
127                     note = li.find_element(By.XPATH,".//div[@class='p-name p-name-type-2']//a//em").text
128                     mark = note.split(" ")[0]
129                     mark = mark.replace("爱心东东\n", "")
130                     mark = mark.replace(",", "")
131                     note = note.replace("爱心东东\n", "")
132                     note = note.replace(",", "")
133 
134                 except:
135                     note = ""
136                     mark = ""
137                     src2 = ""
138                 self.No = self.No + 1
139                 no = str(self.No)
140                 while len(no) < 6:
141                     no = "0" + no
142                     print(no, mark, price)
143                 if src1:
144                     src1 = urllib.request.urljoin(self.driver.current_url, src1)
145                     p = src1.rfind(".")
146                     mFile = no + src1[p:]
147                 elif src2:
148                     src2 = urllib.request.urljoin(self.driver.current_url, src2)
149                     p = src2.rfind(".")
150                     mFile = no + src2[p:]
151                 if src1 or src2:
152                     T = threading.Thread(target=self.download, args=(src1, src2, mFile))
153                     T.setDaemon(False)
154                     T.start()
155                     self.threads.append(T)
156                 else:
157                     mFile = ""
158                 self.insertDB(no, mark, price, note, mFile)
159             try:
160                 self.driver.find_element(By.XPATH,"//span[@class='p-num']//a[@class='pn-prev disabled']")
161             except:
162                 nextPage = self.driver.find_elements(By.XPATH,"//span[@class='p-num']//a[@class='pn-next']")
163                 time.sleep(10)
164                 nextPage.click()
165                 self.processSpider()
166         except Exception as err:
167             print(err)
168 
169     def executeSpider(self, url, key):
170         starttime = datetime.datetime.now()
171         print("Spider starting......")
172         self.startUp(url, key)
173         print("Spider processing......")
174         self.processSpider()
175         print("Spider closing......")
176         self.closeUp()
177         for t in self.threads:
178             t.join()
179         print("Spider completed......")
180         endtime = datetime.datetime.now()
181         elapsed = (endtime - starttime).seconds
182         print("Total ", elapsed, " seconds elapsed")
183 url = "http://www.jd.com"
184 spider = MySpider()
185 while True:
186     print("1.爬取")
187     print("2.显示")
188     print("3.退出")
189     s = input("请选择(1,2,3):")
190     if s == "1":
191         spider.executeSpider(url, "手机")
192         continue
193     elif s == "2":
194         spider.showDB()
195         continue
196     elif s == "3":
197         break

③结果展示:

控制台输出:

数据库存储:

 

 本地文件夹查看:

码云地址:https://gitee.com/shuai321/data-acquisition/blob/master/作业5/exe5.1.py

 (3)心得体会:

        第一题是对老师上课讲的一个例子的复现,通过自己亲自实践对selenium的框架以及使用更加熟悉,对selenium查找HTML元素也做了巩固。但在其中也遇到了一个问题就是在运行完一次后,如果想再次运行就会出错,查看爬取内容时会提示数据库已经锁了,然后我就只能把之前的那张表删掉,然后重新运行建表。后来经过上网查阅发现可能是数据库的活跃状态发生改变。后续还要加强学习!

作业二:

 (1)实验要求:

 要求:

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

        Δ使用Selenium框架+MySQL爬取中国mooc网课程资源信息(课程号、课程名称、教学 进度、课程状态,课程图片地址),同时存储图片到本地项目根目录下的imgs文件夹 中,图片的名称用课程名来存储。 

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

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

设计表头:

Id cCourse cCollege cSchedule cCourseStatus cImgUrl
1

Python网 络爬虫与 信息提取

北京理工 大学 已学3/18 课时 2021年5月18日 已结束

http://edu-i mage.nosd n.127.net/C 0AB6FA791 150F0DFC0 946B9A01C 8CB2.jpg

2

........

       

 

 

 (2)题目分析:

①由于这道题要求我们登录自己的账号爬取课程,所以要先通过查看网页源代码编写登录函数:

找到了登录的位置点击,然后选择其他方式登录

选择手机号登录:

找到输入框,输入账号(手机号)、密码,通过send_keys方发:

 

找到登录按钮,点击即可进入:

 

编写登录函数:

 1 def Load_in():
 2     time.sleep(1)
 3     user = driver.find_element(By.XPATH,'//*[@id="j-topnav"]/div')  # 点击登录
 4     user.click()
 5     time.sleep(1)
 6     way = driver.find_element(By.XPATH,'//div[@class="ux-login-set-scan-code_ft"]/span')  # 选择其他方式登录
 7     way.click()
 8     time.sleep(1)
 9     telephone = driver.find_element(By.XPATH,'//ul[@class="ux-tabs-underline_hd"]/li[2]')  # 选择电话号码登录
10     telephone.click()
11     time.sleep(1)
12     temp_iframe_id = driver.find_elements(By.TAG_NAME,'iframe')[1].get_attribute('id')  #切换至页面弹窗
13     driver.switch_to.frame(temp_iframe_id)
14     driver.find_element(By.XPATH,'//input[@type="tel"]').send_keys('15135075590')  #输入账号
15     time.sleep(1)
16     driver.find_element(By.XPATH,'//input[@class="j-inputtext dlemail"]').send_keys('******')  #输入密码
17     time.sleep(1)
18     load_in = driver.find_element(By.XPATH,'//*[@id="submitBtn"]')  #点击登录
19     load_in.click()

②因为要爬取的课程信息在我的课程中,所以点击进入个人中心:

编写进入个人中心函数:

1 def go_in():
2     time.sleep(2)
3     go_in = driver.find_element(By.XPATH,'//*[@id="j-indexNav-bar"]/div/div/div/div/div[7]/div[3]/div')  # 进入个人中心
4     go_in.click()
5     spider()

③通过查看网页源代码发现,每一个课程的信息都在下图所示的红色方框的标签中:

 图片URL在下图位置:

 课程的其他需要的信息均在下图所示的标签中:

 

编写爬虫函数:

 1 def spider():
 2     global id
 3     time.sleep(3)
 4     divs = driver.find_elements(By.XPATH,'//*[@id="j-coursewrap"]/div/div[1]/div')  #课程列表
 5     print(len(divs))
 6     for i in range(len(divs)):
 7         div = divs[i]
 8         course = div.find_element(By.XPATH,'./div/a/div[2]/div/div/div/span[2]').text  #课程名
 9         collage = div.find_element(By.XPATH,'./div/a/div[2]/div/div[2]/a').text  #开设学校
10         schedule = div.find_element(By.XPATH,'./div[1]/a/div[2]/div[2]/div[1]/div[1]/div[1]/a/span').text  #教学计划
11         coursestatus = div.find_element(By.XPATH,'./div[1]/a/div[2]/div[2]/div[2]').text   #课程状态
12         imgurl = div.find_element(By.XPATH,'./div[1]/a/div[1]/img').get_attribute('src')  #图片url
13         T = threading.Thread(target=download, args=(imgurl, id + 1))  # 创建进程
14         T.start()
15         threads.append(T)
16         id+=1
17         print(id)
18         print(course)
19         print(collage)
20         print(schedule)
21         print(coursestatus)
22         print(imgurl)
23         cursor.execute("insert into mooc(id, course, collage, schedule, coursestatus, imgurl) " 
24                        "values( % s, % s, % s, % s, % s, % s)",
25                        (id, course, collage, schedule, coursestatus, imgurl))

④保存图片函数:

1 def download(img,no):
2     with open('./imgs' + str(no) + '.jpg', 'wb') as imgs:
3         pic = requests.get(img).content
4         imgs.write(pic)

⑤模拟浏览器:

1 url = 'https://www.icourse163.org/'
2 chrome_options = Options()
3 chrome_options.add_argument('--headless')
4 chrome_options.add_argument('--disable-gpu')
5 driver = webdriver.Chrome(options=chrome_options)
6 driver.get(url)
7 driver.maximize_window() #窗口最大化

⑥存入数据库:

1 # 连接数据库
2 con = pymysql.connect(host='localhost', port=3306, user='root', passwd='******', db='MOOC', charset='utf8')
3 cursor = con.cursor(pymysql.cursors.DictCursor)
4 sql = 'create table mooc(id int,course varchar(32),collage varchar(16),schedule varchar(32),coursestatus varchar(64),' \
5       'imgurl varchar(256));'
6 cursor.execute(sql)
7 cursor.execute("delete from mooc")

⑦结果展示:

控制台输出:

数据库展示:

本地文件展示:

码云地址:https://gitee.com/shuai321/data-acquisition/blob/master/作业5/exe5.2.py

(3)心得体会:

         这一题是对selenium的综合应用,包括了查找HTML元素、实现用户模拟登录、爬取Ajax网页数据、等待 HTML元素等内容,总体来说难度较大,做了很久,中途还遇到了一个问题就是在编写爬虫程序时,一直显示爬取的内容为空,检查了XPath语句也没有出错,后来是发现在进入课程中心函数和爬虫程序之间没有设置等待时间,导致页面信息还没有加载出来,才出现爬取内容为空的情况。后续就是考试了,还要多加巩固练习,更加熟练使用selenium!

作业三:

 (1)实验要求:

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

              任务一:开通MapReduce服务

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

              任务三:配置Kafka

              任务四:安装Flume客户端

              任务五:配置Flume采集数据

 (2)实验步骤:

任务一:开通MapReduce服务。(开通步骤较多,不截图展示)

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

编写Python脚本,使用Xshell 7连接服务器:

 ②进入/opt/client/目录,使用vi命令编写Python脚本:vi autodatapython.py(这里直接使用xftp7将本地的autodatapython.py文件上传至服务器/opt/client/目录下即可):

 ③使用mkdir命令在/tmp下创建目录flume_spooldir,我们把Python脚本模拟生成的数据放到此目录下,后面Flume就监控这个文件下的目录,以读取数据。执行Python命令,测试生成100条数据,然后查看数据:

  任务三:配置Kafka:

①首先设置环境变量,执行source命令,使变量生效:

②在kafka中创建topic,查看topic信息:

任务四:安装Flume客户端:

①下载完成后会有弹出框提示下载到哪一台服务器上(这台机器就是Master节点),路径就是/tmp/MRS-client:

 

 ② 解压下载的flume客户端文件:

 ③解压“MRS_Flume_ClientConfig.tar”文件:

 ④ 安装Flume环境变量:

 ⑤解压Flume客户端:

 ⑥ 安装Flume客户端:

 ⑦  重启Flume服务:

 任务五:配置Flume采集数据:

①修改配置文件(注意更换为自己Kafka的ip,端口号一般不动):

 ② 创建消费者消费kafka中的数据:

(3)实验心得:

        学会了如何使用Flume进行实时流前端数据采集,理解了Flume架构和关键特性,掌握了如何使用Flume完成日志采集任务。

        遇到的问题:在任务五配置文件时,使用xftp直接上传了编辑好的文件,然后出错了,原因是在原来的conf文件夹中有一个空的properties文件了。删掉后就解决了。

posted @ 2021-11-26 20:39  哈哈哈GS  阅读(13)  评论(0编辑  收藏  举报