成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

一名合格的數據分析師分享Python網絡爬蟲二三事(綜合實戰案例)

開發 開發工具
作為一名合格的數據分析師,其完整的技術知識體系必須貫穿數據獲取、數據存儲、數據提取、數據分析、數據挖掘、數據可視化等各大部分。

接上篇文章《一名合格的數據分析師分享Python網絡爬蟲二三事》

[[184074]]

五、綜合實戰案例

1. 爬取靜態網頁數據

(1)需求

爬取豆瓣網出版社名字并分別存儲到excel、txt與MySQL數據庫中。

(2)分析

  • 查看源碼
  • Ctrl+F搜索任意出版社名字,如博集天卷
  • 確定正則模式
  1. "<div class="name">(.*?)</div>"  

(3)思路

  • 下載目標頁面
  • 正則匹配目標內容
  • Python列表存儲
  • 寫入Excel/txt/MySQL

(4)源碼

  1. ''信息存儲'''import urllibimport reimport xlsxwriterimport MySQLdb#-----------------(1)存儲到excel與txt-------------------------#def gxls_concent(target_url,pat): 
  2.     ''' 
  3. 功能:爬取數據 
  4.     @target_url:爬取目標網址 
  5.     @pat:數據過濾模式 
  6.     ''' 
  7.     data = urllib.request.urlopen(target_url).read() 
  8.     reret_concent = re.compile(pat).findall(str(data,'utf-8')) 
  9.     return ret_concentdef wxls_concent(ret_xls,ret_concent): 
  10.     ''' 
  11.     功能:將最終結果寫入douban.xls中 
  12.     @ret_xls:最終結果存儲excel表的路徑 
  13.     @ret_concent:爬取數據結果列表 
  14.     ''' 
  15.     # 打開最終寫入的文件 
  16.     wb1 = xlsxwriter.Workbook(ret_xls) 
  17.     # 創建一個sheet工作對象 
  18.     ws = wb1.add_worksheet() 
  19.     try: 
  20.         for i in range(len(ret_concent)): 
  21.             data = ret_concent[i] 
  22.             ws.write(i,0,data) 
  23.         wb1.close() 
  24.     except Exception as er: 
  25.         print('寫入“'+ret_xls+'”文件時出現錯誤') 
  26.         print(er)    def wtxt_concent(ret_txt,ret_concent): 
  27.     ''' 
  28.     功能:將最終結果寫入douban.txt中 
  29.     @ret_xls:最終結果存儲excel表的路徑 
  30.     @ret_concent:爬取數據結果列表 
  31.     ''' 
  32.     fh = open(ret_txt,"wb") 
  33.     try: 
  34.         for i in range(len(ret_concent)): 
  35.             data = ret_concent[i] 
  36.             datadata = data+"\r\n" 
  37.             datadata = data.encode() 
  38.             fh.write(data) 
  39.     except Exception as er: 
  40.         print('寫入“'+ret_txt+'”文件時出現錯誤') 
  41.         print(er)   
  42.     fh.close()def mainXlsTxt(): 
  43.     ''' 
  44.     功能:將數據存儲到excel表中 
  45.     ''' 
  46.     target_url = 'https://read.douban.com/provider/all'  # 爬取目標網址 
  47.     pat = '<div>(.*?)</div>' # 爬取模式 
  48.     ret_xls = "F:/spider_ret/douban.xls"   # excel文件路徑 
  49.     ret_txt = "F:/spider_ret/douban.txt"   # txt文件路徑 
  50.     ret_concent = gxls_concent(target_url,pat) # 獲取數據 
  51.     wxls_concent(ret_xls,ret_concent) # 寫入excel表 
  52.     wtxt_concent(ret_txt,ret_concent) # 寫入txt文件  #---------------------END(1)--------------------------------##-------------------(2)存儲到MySQL---------------------------#def db_con(): 
  53.     ''' 
  54.     功能:連接MySQL數據庫 
  55.     ''' 
  56.     con = MySQLdb.connect( 
  57.         host='localhost',  # port 
  58.         user='root',       # usr_name 
  59.         passwd='xxxx',     # passname 
  60.         db='urllib_data',  # db_name 
  61.         charset='utf8'
  62.         local_infile = 1 
  63.         ) 
  64.     return con   def exeSQL(sql): 
  65.     ''' 
  66. 功能:數據庫查詢函數 
  67.     @sql:定義SQL語句 
  68.     ''' 
  69.     print("exeSQL: " + sql) 
  70.     #連接數據庫 
  71.     con = db_con() 
  72.     con.query(sql)   def gdb_concent(target_url,pat): 
  73.     ''' 
  74.     功能:轉換爬取數據為插入數據庫格式:[[value_1],[value_2],...,[value_n]] 
  75.     @target_url:爬取目標網址 
  76.     @pat:數據過濾模式 
  77.     ''' 
  78.     tmp_concent = gxls_concent(target_url,pat) 
  79.     ret_concent = []    
  80.     for i in range(len(tmp_concent)): 
  81.         ret_concent.append([tmp_concent[i]]) 
  82.     return ret_concentdef wdb_concent(tbl_name,ret_concent): 
  83.     ''' 
  84.     功能:將爬取結果寫入MySQL數據庫中 
  85.     @tbl_name:數據表名 
  86.     @ret_concent:爬取數據結果列表 
  87.     ''' 
  88.     exeSQL("drop table if exists " + tbl_name) 
  89.     exeSQL("create table " + tbl_name + "(pro_name VARCHAR(100));") 
  90.     insert_sql = "insert into " + tbl_name + " values(%s);" 
  91.     con = db_con() 
  92.     cursor = con.cursor() 
  93.     try: 
  94.         cursor.executemany(insert_sql,ret_concent) 
  95.     except Exception as er: 
  96.         print('執行MySQL:"' + str(insert_sql) + '"時出錯')         
  97.         print(er) 
  98.     finally: 
  99.         cursor.close()         
  100.         con.commit() 
  101.         con.close()def mainDb(): 
  102.     ''' 
  103.     功能:將數據存儲到MySQL數據庫中 
  104.     ''' 
  105.     target_url = 'https://read.douban.com/provider/all'  # 爬取目標網址 
  106.     pat = '<div>(.*?)</div>' # 爬取模式 
  107.     tbl_name = "provider" # 數據表名 
  108.     # 獲取數據 
  109.     ret_concent = gdb_concent(target_url,pat) 
  110.     # 寫入MySQL數據庫 
  111.     wdb_concent(tbl_name,ret_concent)  #---------------------END(2)--------------------------------#if __name__ == '__main__': 
  112.     mainXlsTxt() 
  113. mainDb() 


(5)結果

 爬取靜態網頁數據

2. 爬取基于Ajax技術網頁數據

(1)需求

爬取拉勾網廣州的數據挖掘崗位信息并存儲到本地Excel文件中

(2)分析

a. 崗位數據在哪里?

  • 打開拉勾網==》輸入關鍵詞“數據挖掘”==》查看源碼==》沒發現崗位信息
  • 打開拉勾網==》輸入關鍵詞“數據挖掘”==》按F12==》Network刷新==》按下圖操作

我們可以發現存在position和company開頭的json文件,這很可能就是我們所需要的崗位信息,右擊選擇open link in new tab,可以發現其就是我們所需的內容。

右擊選擇open link in new tab

b. 如何實現翻頁?

我們在寫爬蟲的時候需要多頁爬取,自動模擬換頁操作。首先我們點擊下一頁,可以看到url沒有改變,這也就是Ajax(異步加載)的技術。點擊position的json文件,在右側點擊Headers欄,可以發現***部有如下內容:

在右側點擊Headers欄

當我們換頁的時候pn則變為2且first變為false,故我們可以通過構造post表單進行爬取。

c. Json數據結構怎么樣?

Json數據結構

(3)源碼

  1. import urllib.requestimport urllib.parseimport socketfrom multiprocessing.dummy import Poolimport jsonimport timeimport xlsxwriter#----------------------------------------------------------#######(1)獲取代理IP###def getProxies(): 
  2.   ''' 
  3.   功能:調用API獲取原始代理IP池 
  4.   ''' 
  5.   url = "http://api.xicidaili.com/free2016.txt" 
  6.   i_headers={"User-Agent":"Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.22 Safari/537.36 SE 2.X MetaSr 1.0"} 
  7.   global proxy_addr 
  8.   proxy_addr = [] 
  9.   try: 
  10.       req = urllib.request.Request(url,headers = i_headers
  11.       proxy = urllib.request.urlopen(req).read() 
  12.       proxyproxy = proxy.decode('utf-8') 
  13.       proxyproxy_addr = proxy.split('\r\n')  #設置分隔符為換行符 
  14.   except Exception as er: 
  15.       print(er) 
  16.   return proxy_addr   def testProxy(curr_ip): 
  17.   ''' 
  18.   功能:利用百度首頁,逐個驗證代理IP的有效性 
  19.   @curr_ip:當前被驗證的IP 
  20.   ''' 
  21.   socket.setdefaulttimeout(5)  #設置全局超時時間 
  22.   tarURL = "https://www.baidu.com/"  #測試網址 
  23.   proxy_ip = [] 
  24.   try: 
  25.       proxy_support = urllib.request.ProxyHandler({"http":curr_ip}) 
  26.       opener = urllib.request.build_opener(proxy_support) 
  27.       opener.addheaders=[("User-Agent","Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.22 Safari/537.36 SE 2.X MetaSr 1.0")] 
  28.       urllib.request.install_opener(opener) 
  29.       res = urllib.request.urlopen(tarURL).read() 
  30.       proxy_ip.append(curr_ip) 
  31.       print(len(res)) 
  32.   except Exception as er: 
  33.       print("驗證代理IP("+curr_ip+")時發生錯誤:"+er) 
  34.   return proxy_ip   def mulTestProxies(proxies_ip): 
  35.   ''' 
  36.   功能:構建多進程驗證所有代理IP 
  37.   @proxies_ip:代理IP池 
  38.   ''' 
  39.   pool = Pool(processes=4)  #開啟四個進程 
  40.   proxies_addr = pool.map(testProxy,proxies_ip) 
  41.   pool.close() 
  42.   pool.join()  #等待進程池中的worker進程執行完畢 
  43.   return proxies_addr#----------------------------------------------------------#######(2)爬取數據###def getInfoDict(url,page,pos_words_one,proxy_addr_one): 
  44.   ''' 
  45.   功能:獲取單頁職位數據,返回數據字典 
  46.   @url:目標URL 
  47.   @page:爬取第幾頁 
  48.   @pos_words_one:搜索關鍵詞(單個) 
  49.   @proxy_addr_one:使用的代理IP(單個) 
  50.   ''' 
  51.   global pos_dict 
  52.   page = 1 
  53.   i_headers=("User-Agent","Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.22 Safari/537.36 SE 2.X MetaSr 1.0") 
  54.   proxy = urllib.request.ProxyHandler({"http":proxy_addr_one}) 
  55.   opener = urllib.request.build_opener(proxy,urllib.request.HTTPHandler) 
  56.   opener.addheaders=[i_headers] 
  57.   urllib.request.install_opener(opener) 
  58.   if page==1: 
  59.       tORf = "true" 
  60.   else: 
  61.       tORf = "false" 
  62.   mydata = urllib.parse.urlencode({"first": tORf,            
  63.                                    "pn": page,           #pn變化實現翻頁 
  64.                                    "kd": pos_words_one } ).encode("utf-8") 
  65.   try: 
  66.       req = urllib.request.Request(url,mydata) 
  67.       data=urllib.request.urlopen(req).read().decode("utf-8","ignore")  #利用代理ip打開 
  68.       pos_dict = json.loads(data)  #將str轉成dict 
  69.   except urllib.error.URLError  as er: 
  70.       if hasattr(er,"code"): 
  71.           print("獲取職位信息json對象時發生URLError錯誤,錯誤代碼:") 
  72.           print(er.code) 
  73.       if hasattr(er,"reason"): 
  74.           print("獲取職位信息json對象時發生URLError錯誤,錯誤原因:") 
  75.           print(er.reason) 
  76.   return pos_dictdef getInfoList(pos_dict): 
  77.   ''' 
  78.   功能:將getInfoDict()返回的數據字典轉換為數據列表 
  79.   @pos_dict:職位信息數據字典 
  80.   ''' 
  81.   pos_list = []  #職位信息列表    
  82.   jcontent = pos_dict["content"]["positionResult"]["result"]     
  83.   for i in jcontent:         
  84.       one_info = []  #一個職位的相關信息       
  85.       one_info.append(i["companyFullName"])         
  86.       one_info.append(i['companySize'])         
  87.       one_info.append(i['positionName'])         
  88.       one_info.append(i['education'])         
  89.       one_info.append(i['financeStage'])         
  90.       one_info.append(i['salary'])         
  91.       one_info.append(i['city'])         
  92.       one_info.append(i['district'])         
  93.       one_info.append(i['positionAdvantage'])         
  94.       one_info.append(i['workYear'])         
  95.       pos_list.append(one_info) 
  96.   return pos_listdef getPosInfo(pos_words,city_words,proxy_addr): 
  97.   ''' 
  98.   功能:基于函數getInfoDict()與getInfoList(),循環遍歷每一頁獲取最終所有職位信息列表 
  99.   @pos_words:職位關鍵詞(多個) 
  100.   @city_words:限制城市關鍵詞(多個) 
  101.   @proxy_addr:使用的代理IP池(多個) 
  102.   ''' 
  103.   posInfo_result = []     
  104.   title = ['公司全名', '公司規模', '職位名稱', '教育程度', '融資情況', "薪資水平", "城市", "區域", "優勢", "工作經驗"]     
  105.   posInfo_result.append(title)   
  106.   for i in range(0,len(city_words)): 
  107.       #i = 0 
  108.       key_city = urllib.request.quote(city_words[i]) 
  109.       #篩選關鍵詞設置:gj=應屆畢業生&xl=大專&jd=成長型&hy=移動互聯網&px=new&city=廣州 
  110.       url = "https://www.lagou.com/jobs/positionAjax.json?city="+key_city+"&needAddtionalResult=false
  111.       for j in range(0,len(pos_words)): 
  112.           #j = 0 
  113.           page=1 
  114.           while page<10:  #每個關鍵詞搜索拉鉤顯示30頁,在此只爬取10頁 
  115.               pos_wordspos_words_one = pos_words[j] 
  116.               #k = 1 
  117.               proxy_addrproxy_addr_one = proxy_addr[page] 
  118.               #page += 1 
  119.               time.sleep(3) 
  120.               pos_info = getInfoDict(url,page,pos_words_one,proxy_addr_one)  #獲取單頁信息列表 
  121.               pos_infoList = getInfoList(pos_info) 
  122.               posInfo_result += pos_infoList  #累加所有頁面信息        
  123.               page += 1    
  124.   return posInfo_result#----------------------------------------------------------#######(3)存儲數據###def wXlsConcent(export_path,posInfo_result): 
  125.   ''' 
  126.   功能:將最終結果寫入本地excel文件中 
  127.   @export_path:導出路徑 
  128.   @posInfo_result:爬取的數據列表 
  129.   ''' 
  130.   # 打開最終寫入的文件 
  131.   wb1 = xlsxwriter.Workbook(export_path) 
  132.   # 創建一個sheet工作對象 
  133.   ws = wb1.add_worksheet() 
  134.   try: 
  135.       for i in range(0,len(posInfo_result)): 
  136.           for j in range(0,len(posInfo_result[i])): 
  137.               data = posInfo_result[i][j] 
  138.               ws.write(i,j,data) 
  139.       wb1.close() 
  140.   except Exception as er: 
  141.       print('寫入“'+export_path+'”文件時出現錯誤:') 
  142.       print(er)#----------------------------------------------------------#######(4)定義main()函數###def main(): 
  143.   ''' 
  144.   功能:主函數,調用相關函數,最終輸出路徑(F:/spider_ret)下的positionInfo.xls文件     
  145.   ''' 
  146.   #---(1)獲取代理IP池 
  147.   proxies = getProxies()  #獲取原始代理IP    
  148.   proxy_addr = mulTestProxies(proxies) #多線程測試原始代理IP 
  149.   #---(2)爬取數據 
  150.   search_key = ["數據挖掘"]  #設置職位關鍵詞(可以設置多個) 
  151.   city_word = ["廣州"]  #設置搜索地區(可以設置多個) 
  152.   posInfo_result = getPosInfo(search_key,city_word,proxy_addr) #爬取職位信息 
  153.   #---(3)存儲數據 
  154.   export_path = "F:/spider_ret/positionInfo.xls" #設置導出路徑 
  155.   wXlsConcent(export_path,posInfo_result)  #寫入到excel中           if __name__ == "__main__": 
  156.   main() 

接下篇文章《一名合格的數據分析師分享Python網絡爬蟲二三事(Scrapy自動爬蟲)》

【本文是51CTO專欄機構“豈安科技”的原創文章,轉載請通過微信公眾號(bigsec)聯系原作者】

戳這里,看該作者更多好文

責任編輯:趙寧寧 來源: 51CTO專欄
相關推薦

2017-02-23 17:46:11

數據分析師Python網絡爬蟲

2017-02-23 18:41:03

數據分析師Python網絡爬蟲

2015-08-04 13:25:46

數據分析

2014-06-19 14:00:46

數據分析師

2017-12-11 15:56:44

數據分析師數據倉庫數據源

2017-09-19 13:35:47

數據科學數據分析python

2016-11-11 20:38:39

數據分析師大數據

2012-06-08 10:12:08

架構師

2015-08-18 13:26:05

數據分析

2013-04-11 10:03:55

2016-10-21 14:41:22

數據分析師大數據

2015-09-30 09:36:58

數據分析師面試offer

2012-08-08 09:00:29

數據分析師

2022-11-11 11:35:14

2012-08-07 17:32:25

數據分析師

2021-03-26 07:37:34

數據分析工具技能

2023-07-08 23:05:01

數據分析運營

2020-05-12 10:44:19

數據分析師薪資數據

2023-08-25 16:33:10

2017-02-13 19:25:24

點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: 日韩av在线中文字幕 | 欧美中文视频 | 亚洲午夜在线 | 一区二区三区四区在线视频 | 亚洲www啪成人一区二区 | 久久国产精品免费一区二区三区 | 特黄特色大片免费视频观看 | 国产一区二区三区免费视频 | 午夜二区 | 精品国产一区二区三区久久 | 久久国产视频播放 | 国产精品一区二区三区久久 | 中文字幕国产日韩 | 久久久久国产 | 亚洲一区二区三区在线播放 | 国产精品不卡 | 日日久 | 男女免费观看在线爽爽爽视频 | 日韩一二区在线 | 亚洲成人精 | 亚洲一区二区三区免费在线观看 | 亚洲精品高清视频 | 中文字幕高清在线 | 精品国产乱码久久久久久闺蜜 | 亚洲一区二区三区高清 | 亚洲第一视频 | 色婷婷av99xx | 午夜欧美一区二区三区在线播放 | 欧美一区二区三区小说 | 男女羞羞免费视频 | 欧美福利在线 | 精品一区欧美 | 91色综合 | 亚洲最新网址 | 国产高清视频在线观看播放 | 国产一区二区三区精品久久久 | 日韩精品免费在线观看 | 伊人影院在线观看 | 人成精品| 日韩一区二区在线视频 | xx视频在线 |