python 基礎 網路爬蟲 day05
阿新 • • 發佈:2018-12-18
目錄
day04
- lxml解析庫
- 使用流程
- from lxml import etree
- parseHtml = etree.HTML(html)
- parseHtml.xpath('xpath表示式')
- xpath匹配規則
- 獲取節點物件://div[@class="Tiger"]
- 獲取節點屬性值://div[@class="T"]//a/@src
- 函式://div[contains(@class,"a")]//a/@href
- xpath高階
- 基準xpath表示式(節點物件列表)
- for r in [節點物件列表]: username = parseHtml.xpath('./xpath表示式') ... ...
- 使用流程
day05
1.json模組
- 什麼是json? javascript中的物件和陣列 物件:{key:value} 取值:物件名.key 陣列:[...,...] 取值:陣列[索引值]
- 作用 json格式的字串 和 python資料型別 之間的轉換
- 常用方法
- json.loads():json格式 --> Python資料型別
json python
物件 字典
陣列 列表
'''01_json.loads示例.py''' import json # json格式的陣列 jsarray = '[1,2,3,4]' # 陣列 -> 列表 L = json.loads(jsarray) print(type(L),L) # json格式物件 jsobj = '{"city":"天地會","name":"步驚雲"}' # 物件 -> 字典 D = json.loads(jsobj) print(type(D),D)
- json.dumps():Python資料型別 --> json格式
python json
字典 物件
列表 陣列
元組 陣列
##注意:'''02_json.dunps示例.py''' import json L = [1,2,3,4] T = (1,2,3,4) D = {"city":"天地會","name":"聶風"} # python格式 -> json格式 jsarray1 = json.dumps(L) print(type(jsarray1),jsarray1) jsarray2 = json.dumps(T) print(type(jsarray2),jsarray2) jsobj = json.dumps(D,ensure_ascii=False) print(type(jsobj),jsobj)
- json.dumps()預設使用的是ascii編碼
- 新增引數ensure_ascii=False,禁用ascii編碼
- json.loads():json格式 --> Python資料型別
json python
物件 字典
陣列 列表
2.動態網站資料抓取 - Ajax
- 特點:滾動滑鼠滑輪時載入
- 案例:豆瓣電影排行榜資料抓取
- 抓取目標:豆瓣電影 - 排行榜 - 劇情 電影名稱,評分
- 程式碼實現
稍微高階點'''03_豆瓣電影抓取-Ajax.py''' import requests import json import csv num=input('請輸入要爬取的數量:') url='https://movie.douban.com/j/chart/top_list' headers={ 'User-Agent':'Mozilla/5.0', } params={ "type":"11", "interval_id":"100:90", "action":'', "start":"0", "limit":num, } res=requests.get(url,params=params,headers=headers) res.encoding='utf-8' # html為json格式的陣列[{電影1資訊},{},{}] html=res.text html=json.loads(html) #print(html) #用for迴圈遍歷每一個電影資訊 with open('豆瓣電影.csv','a',newline='') as f: writer=csv.writer(f) for film in html: name=film['title'] score=film['rating'][0] L=[name,score] writer.writerow(L)
'''03_豆瓣電影抓取-Ajax.py''' import requests import json import csv # url要寫抓到的GET :URL url = "https://movie.douban.com/j/chart/top_list?" headers = {"User-Agent":"Mozilla/5.0"} L = ["劇情","喜劇","動作"] tp_list = [{"劇情":"11"},{"喜劇":"24"},{"動作":"5"}] tp = input("請輸入電影型別:") if tp in L: num = input("請輸入要爬取的數量:") for film_dict in tp_list: for key,value in film_dict.items(): if tp == key: params = { "type":value, "interval_id":"100:90", "action":"", "start":"0", "limit":num } res = requests.get(url,params=params,headers=headers) res.encoding = "utf-8" # html為json格式的陣列[{電影1資訊},{},{}] html = res.text # 陣列 -> 列表 html = json.loads(html) # 用for迴圈遍歷每一個電影資訊{} for film in html: name = film['title'] score = film["rating"][0] #{"rating":["9.6","50"],...} with open("豆瓣電影.csv","a",newline="") as f: writer = csv.writer(f) L = [name,score] writer.writerow(L) else: print("您輸入的型別不存在!")
3.selenium + phantomjs 強大的網路爬蟲組合
- selenium
- 定義:Web自動化測試工具,應用於Web自動化測試
- 特點
- 可以執行在瀏覽器,根據指定命令操作瀏覽器,讓瀏覽器自動載入頁面
- 只是工具,不支援瀏覽器功能,需要與第三方瀏覽器結合使用
- phantomjs
- 定義:無介面瀏覽器(無頭瀏覽器)
- 特點
- 把網站載入到記憶體進行頁面載入
- 執行高效
- 安裝
- windows
- 將下載的可執行檔案放到Python安裝目錄的Scripts目錄下 在cmd下搜尋 where python 然後找到python地址,放到Scripts目錄
- Ubuntu
- 將下載的phantomjs放到一個路徑下
- 新增環境變數 vi .bashrc 新增 export PHANTOM_JS=/home/.../phantomjs-2.1.1-... export PATH=$PHANTOM_JS/bin:$PATH 終端:source .bashrc 終端:phantomjs
- windows
- 示例程式碼
- 示例程式碼1:
'''05_phantomjs+selenium示例1.py''' # 匯入selenium庫中的webdriver介面 from selenium import webdriver # 建立phantomjs瀏覽器物件 driver = webdriver.PhantomJS() # 發請求 get() driver.get("http://www.baidu.com/") print(driver.page_source) ## 獲取網頁截圖 #driver.save_screenshot("百度.png") #print("圖片儲存成功") ## 關閉 #driver.quit()
- 示例程式碼2:
'''06_phantomjs+selenium示例2.py''' from selenium import webdriver import time # 建立瀏覽器物件 driver = webdriver.PhantomJS() # 開啟頁面 driver.get("http://www.baidu.com/") # 傳送文字到搜尋框 kw = driver.find_element_by_id("kw") kw.send_keys("美女") # 點選 "百度一下" su = driver.find_element_by_id("su") su.click() time.sleep(1) # 獲取截圖 driver.save_screenshot("美女.png") # 關閉瀏覽器 driver.quit()
- 示例程式碼1:
- 常用方法
- driver.get(url) 開啟網站
- driver.page_source:獲取響應的html原始碼
- driver.page_source.find('字串')
- 作用:從html原始碼中搜索指定字串 -1:查詢失敗 非-1:查詢成功
- 單元素查詢
- driver.find_element_by_id(" ").text
- driver.find_element_by_class_name(" ")
- driver.find_element_by_xpath('xpath表示式')
- 如果匹配到多個節點,則只返回第一個節點物件
- 多元素查詢
- driver.find_elements_by_...
- 注意
- 如果結果1個,則返回節點物件,不是列表
- 如果結果n個,則返回列表
- 示例
'''08_driver.find查詢元素示例.py''' from selenium import webdriver driver = webdriver.Chrome() driver.get("https://www.qiushibaike.com/") # 查詢單個節點 element r_One = driver.find_element_by_class_name("content") print(r_One.text) # 查詢多個節點 elements r_Many = driver.find_elements_by_class_name("content") for r in r_Many: print(r.text) print() driver.quit()
- 物件名.send_keys("內容")
- 物件名.click()
- 案例1:登入豆瓣網站
'''09_selenium+Chrome登陸豆瓣案例.py''' from selenium import webdriver import time # 建立瀏覽器物件,發請求 driver = webdriver.Chrome() driver.get("https://www.douban.com/") time.sleep(0.5) # 獲取截圖(驗證碼) driver.save_screenshot("驗證碼.png") # 找 使用者名稱、密碼、驗證、登陸豆瓣按鈕 uname = driver.find_element_by_name("form_email") uname.send_keys("19921510089") # 密碼 pwd = driver.find_element_by_name("form_password") pwd.send_keys("zhanshen001") # 驗證碼 key = input("請輸入驗證碼:") yzm = driver.find_element_by_id("captcha_field") yzm.send_keys(key) driver.save_screenshot("完成.png") # 點選登陸按鈕 login = driver.find_element_by_class_name("bn-submit") login.click() time.sleep(1) driver.save_screenshot("登陸成功.png") # 關閉瀏覽器 driver.quit()
- 操作鍵盤
- 導模組 from selenium.webdrier.common.keys import Keys
- 常用方法
'''10_driver操作鍵盤示例.py''' from selenium import webdriver # 操作鍵盤 from selenium.webdriver.common.keys import Keys import time # 建立瀏覽器物件,發請求 driver = webdriver.Chrome() driver.get("http://www.baidu.com/") # 百度搜索框輸入python kw = driver.find_element_by_id("kw") kw.send_keys("python") driver.save_screenshot("01_python.png") # 全選 :Ctrl + a kw = driver.find_element_by_id("kw") kw.send_keys(Keys.CONTROL,'a') driver.save_screenshot("02_CtrlA.png") # 剪下 :Ctrl + x kw = driver.find_element_by_id("kw") kw.send_keys(Keys.CONTROL,'x') driver.save_screenshot("03_CtrlX.png") # 貼上 :Ctrl + v kw = driver.find_element_by_id("kw") kw.send_keys(Keys.CONTROL,'v') driver.save_screenshot("04_CtrlV.png") # 清空搜尋框 : 物件名.clear() kw = driver.find_element_by_id("kw") kw.clear() driver.save_screenshot("05_Clear.png") # 輸入 :達內科技 kw = driver.find_element_by_id("kw") kw.send_keys("達內科技") driver.save_screenshot("06_Tarena.png") # 輸入 :回車 kw = driver.find_element_by_id("kw") kw.send_keys(Keys.ENTER) time.sleep(1) driver.save_screenshot("07_Enter.png") # 關閉瀏覽器 driver.quit()
- 案例2:鬥魚直播網站主播資訊抓取
- 抓取目標:主播名稱,觀眾人數
- 主播:class -- dy-name ellipsis fl //div[@id="live-list-content"]//span[@class="dy-name ellipsis fl"]
- 人數:class -- dy-num fr //div[@id="live-list-content"]//span[@class="dy-num fr"]
- 下一頁按鈕(能點的按鈕):class -> shark-pager-next
- 下一頁按鈕(不能點的按鈕):
- 程式碼實現
'''11_鬥魚直播抓取案例.py''' from selenium import webdriver from lxml import etree import time # 把Chrome設定無介面瀏覽器 opt = webdriver.ChromeOptions() opt.set_headless() # 建立瀏覽器物件,發請求 driver = webdriver.Chrome(options=opt) driver.get("https://www.douyu.com/directory/all") i = 1 # 迴圈 while True: # 解析(driver.page_source) # 獲取主播名稱 和 觀眾人數 parseHtml = etree.HTML(driver.page_source) names = parseHtml.xpath('//div[@id="live-list-content"]//span[@class="dy-name ellipsis fl"]') numbers = parseHtml.xpath('//div[@id="live-list-content"]//span[@class="dy-num fr"]') for name,number in zip(names,numbers): print("\t主播名稱:%s \t觀眾人數:%s" % (name.text.strip(),number.text.strip())) #for name,number in [("主播1","20萬"),("主播2","15萬")] print("第%d頁爬取成功" % i) i += 1 # 判斷是否需要點選下一頁 # 能點 :點選,繼續迴圈 if driver.page_source.find("shark-pager-disable-next") == -1: driver.find_element_by_class_name("shark-pager-next").click() time.sleep(1) else: break # 不能點 :break print("一共爬取了%d頁" % i)
- 抓取目標:主播名稱,觀眾人數
- Chromdriver如何設定無介面模式 1、opt = webdriver.ChromeOptions() 2、opt.set_headless() 3、driver = webdriver.Chrome(options=opt) 4、driver.get(url)
- 案例3:京東商品爬取
- 目標
- 商品名稱
- 商品價格
- 評論數量
- 商家名稱
- 程式碼實現
'''12_京東商品爬取.py''' from selenium import webdriver import time import csv # 接受使用者輸入,訪問京東 pro = input("請輸入要爬取的商品:") driver = webdriver.Chrome() driver.get("https://www.jd.com/") i = 1 # 傳送文字到搜尋框,點選搜尋 text = driver.find_element_by_class_name("text") text.send_keys(pro) button = driver.find_element_by_class_name("button") button.click() time.sleep(1) while True: # 動態載入-->全部載入 # 執行指令碼,進度條拉到底部 driver.execute_script( 'window.scrollTo(0,\ document.body.scrollHeight)') time.sleep(2) # 正常解析爬取 r_list = driver.find_elements_by_xpath\ ('//div[@id="J_goodsList"]//li') # r為每一個商品的節點物件 for r in r_list: m = r.text.split('\n') # ["¥52.80","Python...","200+",] price = m[0] name = m[1] commit = m[2] market = m[3] with open("商品.csv","a",newline="",encoding="gb18030") as f: writer = csv.writer(f) L = [name.strip(),price.strip(), commit.strip(),market.strip()] writer.writerow(L) print("第%d頁爬取成功" % i) i += 1 # 點選下一頁 #未寫迴圈
-
小提示:
JS控制滾動條的位置: window.scrollTo(x,y);
豎向滾動條置頂(window.scrollTo(0,0); 豎向滾動條置底 window.scrollTo(0,document.body.scrollHeight) 當前視窗driver.execute_script('window.scrollTo(0,document.body.scrollHeight)')
- 目標
今日示例