天天看點

Python網絡爬蟲(JSON, Phantomjs, selenium/Chromedirver,豆瓣電影、鬥魚直播、京東商城爬取)

個人網站剛上線 捧捧場  謝謝~

項目還是遇到跟多坑的  分享一下

www.baliIT.com 域名備案中  如果不能通路 可以嘗試 

http://106.12.86.182/
Python網絡爬蟲(JSON, Phantomjs, selenium/Chromedirver,豆瓣電影、鬥魚直播、京東商城爬取)

json子產品

   什麼是json?

      javascript中的對象和數組

      對象 :{key:value}  取值:對象名.key

      數組 :[...,...] 取值:數組[索引值]

    作用

      json格式的字元串 和 Python資料類型 之間的轉換

    常用方法

      json.loads() : json格式 --> Python資料類型

        json      python

      對象      字典

      數組      清單

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

      字典         對象

      清單         數組

      元組         數組

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編碼

動态網站資料抓取 - Ajax

    特點 :滾動滑鼠滑輪時加載

豆瓣電影排行榜資料抓取

    抓取目标 :豆瓣電影 - 排行榜 - 劇情 

                  電影名稱 、評分

import json
import requests
import csv


def get_movie(typ, number):
    url = "https://movie.douban.com/j/chart/top_list?"
    headers = {"Users-Agent": "Mozilla/5.0"}
    params = {
        "type": typ,
        "interval_id": "100:90",
        "action": "",
        "start": "0",
        "limit": number
    }

    res = requests.get(url, params=params, headers=headers)
    res.encoding = "utf-8"
    # html 為json數組 [{}, {}, {}...]
    html = res.text
    # 數組 -> 清單
    html = json.loads(html)
    # 用for循環周遊每一個電影資訊{}
    for film in html:
        L = [film["title"], film["rating"][0]]
        # {"rating":["9.6","50"],...}
        with open("douban.csv", "a", newline="") as f:
            writer = csv.writer(f)
            writer.writerow(L)


dic = {
    "劇情": "11",
    "喜劇": "24",
    "動作": "5",
    "愛情": "13",
    "動畫": "25",
    "驚悚": "19",
    "科幻": "17",
}
cmd = input("請輸入電影類型:")
try:
    cmd = cmd.strip()
    get_movie(dic[cmd], input("請輸入數量:"))
except KeyError:
    print("類型不存在")
else:
    print("爬取成功呢")
           

selenium + phantomjs 強大的網絡爬蟲組合

    selenium

    定義 :Web自動化測試工具,應用于Web自動化測試

    特點

      可以運作在浏覽器,根據指定指令操作浏覽器,讓浏覽器自動加載頁面

      隻是工具,不支援浏覽器功能,需要與第三方浏覽器結合使用

    phantomjs

      定義 :無界面浏覽器(無頭浏覽器)

      特點

        把網站加載到記憶體進行頁面加載

        運作高效

      安裝

      Windows

        将下載下傳的可執行檔案放到Python安裝目錄的Scripts目錄下

  C:\Python36\Scripts

      Ubuntu

        将下載下傳的phantomjs放到一個路徑下

添加環境變量:

  vi .bashrc 添加

  export PHANTOM_JS=/home/.../phantomjs-2.1.1-...

  export PATH=$PHANTOM_JS/bin:$PATH

  終端:source .bashrc

  終端:phantomjs

# 導入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()



           
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()                

  常用方法

    driver.get(url)

    driver.page_source : 擷取響應的html源碼

    driver.page_source.find("字元串")

      作用 :從html源碼中搜尋指定字元串

         -1 :查找失敗

 非-1   :查找成功

driver = webdriver.PhantomJS()
driver.get("http://www.baidu.com/")
r = driver.page_source.find("ABCDEFG")           

  單元素查找

      1、driver.find_element_by_id("").text

      2、driver.find_element_by_class_name("")

      3、driver.find_element_by_xpath('xpath表達式')

      4、如果比對到多個節點,則隻傳回第1個節點對象

      多元素查找

        driver.find_elements_by_....

        注意

          如果結果1個,則傳回節點對象,不是清單

如果結果N個,則傳回清單

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 :登入豆瓣網站

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("賬号")
# 密碼
pwd = driver.find_element_by_name("form_password")
pwd.send_keys("密碼")
# 驗證碼
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

      常用方法

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()
           

鬥魚直播網站主播資訊抓取(JS分頁加載)

      抓取目标 :主播名稱 、觀衆人數

        主播 :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

      下一頁按鈕(不能點)

        class -> shark-pager-next shark-pager-disable shark-pager-disable-next

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)           

京東商品爬取

    1、目标

      1、商品名稱

      2、商品價格

      3、評論數量

      4、商家名稱

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
    # 點選下一頁