selenium+phantomjs爬取bilibili

selenium+phantomjs爬取bilibili

首先咱們要下載phantomjs 你能夠到 http://phantomjs.org/download.html 這裏去下載 下載完以後解壓到你想要放的位置 你須要配置一下環境變量哦html

以下圖:
enter description herepython


首先,咱們怎麼讓瀏覽器模擬操做,也就是咱們本身先分析好整個操做過程,哪一個地方有什麼問題,把這些問題都提早測試好,沒問題了再進行寫代碼。web

打開bilibili網站 https://www.bilibili.com/ 發現下圖登錄彈窗
enter description here瀏覽器

那麼這裏咱們就得先把這個彈窗去除,怎麼去呢?你刷新一下或者點一下 首頁 就不會出現了,因此這裏咱們能夠模擬再刷新一次或者點擊首頁。app

接下來搜索關鍵詞 蔡徐坤 打球 這時就涉及到搜索輸入框和搜索按鈕
enter description hereide

點擊搜索後咱們看到了下列內容,其中圈起來的就是要爬的信息啦 這時就涉及到頁面源碼獲取,數據元素定位
enter description here測試

那麼上面這個過程走完了的話 咱們也能夠選擇寫入xls格式,同時這裏還少了一個事,那就是我如今才爬了一頁,那難道不寫個自動化爬取所有嗎?
enter description here網站

那此時就得解決循環獲取和寫入xls 更重要的事怎麼去操做頁數和下一頁按鈕ui

大體的思路就是這樣子了!!!編碼

先導入這些模塊

from selenium import webdriver
from selenium.common.exceptions import TimeoutException #一條命令在足夠的時間內沒有完成則會拋出異常
from selenium.webdriver.common.by import By #支持的定位器分類
from selenium.webdriver.support.ui import WebDriverWait  #等待頁面加載完成,找到某個條件發生後再繼續執行後續代碼,若是超過設置時間檢測不到則拋出異常
from selenium.webdriver.support import expected_conditions as EC #判斷元素是否加載
from bs4 import BeautifulSoup
import xlwt

定義一個瀏覽器對象並設置其餘功能

browser = webdriver.Chrome() #初始化瀏覽器對象
WAIT = WebDriverWait(browser,10)  #顯式等待,等待的時間是固定的,這裏爲10秒 元素在指定時間內不可見就引起異常TimeoutException
browser.set_window_size(1400,900) #設置瀏覽器窗口大小

建立excel文件,再建立一張工做表,名爲 蔡徐坤籃球,而且設置支持覆蓋原數據!

book=xlwt.Workbook(encoding='utf-8',style_compression=0) #建立excel文件,設置utf-8編碼,這樣就能夠在excel中輸出中文了
sheet=book.add_sheet('蔡徐坤籃球',cell_overwrite_ok=True) #添加一張工做表 cell_overwrite_ok=True 時能夠覆蓋原單元格中數據。
sheet.write(0,0,'名稱')
sheet.write(0,1,'地址')
sheet.write(0,2,'描述')
sheet.write(0,3,'觀看次數')
sheet.write(0,4,'彈幕數')
sheet.write(0,5,'發佈時間')

打開網站

browser.get('https://www.bilibili.com/')

尋找 「首頁」 元素

index = WAIT.until(EC.element_to_be_clickable((By.CSS_SELECTOR,'#primary_menu > ul > li.home > a')))
        # 配合WebDriverWait類的until()方法進行靈活判斷 進行下一步操做
        # 經過EC進行判斷某個元素中是否可見而且是enable的 這樣的話叫clickable(可點擊)
        # 使用CSS選擇器選中頁面中的 首頁 進行點擊 目的爲了第一次有個登陸彈窗 刷新就沒有 那就點擊下首頁來實現刷新
        index.click() #點擊!

先判斷是否加載 輸入框 再判斷搜索按鈕是否能點擊 達到條件後輸入內容進行搜索

input = WAIT.until(EC.presence_of_element_located((By.CSS_SELECTOR,'#banner_link > div > div > form > input'))) #判斷某個元素是否被加到DOM樹裏,並不表明該元素必定可見(元素能夠是隱藏的)
        submit = WAIT.until(EC.element_to_be_clickable((By.XPATH,'//*[@id="banner_link"]/div/div/form/button'))) #判斷搜索按鈕是否能點擊,這裏使用Xpath來尋找元素
        input.send_keys('蔡徐坤 籃球') #用send_keys()方法進行搜索輸入框中輸入內容
        submit.click() #點擊搜索!

這時搜索完 是彈出新的窗口 這時就得獲取窗口句柄 實現標籤頁跳轉

all_h = browser.window_handles #獲取全部窗口句柄
browser.switch_to.window(all_h[1]) #switch_to.window 標籤頁跳轉

接下來就是獲取頁面源碼了(此處非所有源碼)

WAIT.until(EC.presence_of_element_located((By.CSS_SELECTOR,'#server-search-app > div.contain > div.body-contain > div > div.result-wrap.clearfix'))) #堅持是否加載完全部搜索結果
    html = browser.page_source #page_source方法能夠獲取到頁面源碼

而後搜索元素並提取內容進行保存

#遍歷全部搜索信息 並保存
    list = soup.find(class_='all-contain').find_all(class_='info')
    for item in list:
        item_title = item.find('a').get('title')
        item_link = item.find('a').get('href')
        item_dec = item.find(class_='des hide').text
        item_view = item.find(class_='so-icon watch-num').text
        item_biubiu = item.find(class_='so-icon hide').text
        item_date = item.find(class_='so-icon time').text

        print('爬取:' + item_title)

再最後就是循環獲取每一頁提取數據最後寫入xls文件!!!

下面就直接貼出代碼了

from selenium import webdriver
from selenium.common.exceptions import TimeoutException #一條命令在足夠的時間內沒有完成則會拋出異常
from selenium.webdriver.common.by import By #支持的定位器分類
from selenium.webdriver.support.ui import WebDriverWait  #等待頁面加載完成,找到某個條件發生後再繼續執行後續代碼,若是超過設置時間檢測不到則拋出異常
from selenium.webdriver.support import expected_conditions as EC #判斷元素是否加載
from bs4 import BeautifulSoup
import xlwt


browser = webdriver.Chrome() #初始化瀏覽器對象
WAIT = WebDriverWait(browser,10)  #顯式等待,等待的時間是固定的,這裏爲10秒 元素在指定時間內不可見就引起異常TimeoutException
browser.set_window_size(1400,900) #設置瀏覽器窗口大小


book=xlwt.Workbook(encoding='utf-8',style_compression=0) #建立excel文件,設置utf-8編碼,這樣就能夠在excel中輸出中文了
sheet=book.add_sheet('蔡徐坤籃球',cell_overwrite_ok=True) #添加一張工做表 cell_overwrite_ok=True 時能夠覆蓋原單元格中數據。
sheet.write(0,0,'名稱')
sheet.write(0,1,'地址')
sheet.write(0,2,'描述')
sheet.write(0,3,'觀看次數')
sheet.write(0,4,'彈幕數')
sheet.write(0,5,'發佈時間')
n = 1

def seach():
    try:
        print('開始訪問b站....')
        browser.get('https://www.bilibili.com/')

        index = WAIT.until(EC.element_to_be_clickable((By.CSS_SELECTOR,'#primary_menu > ul > li.home > a')))
        # 配合WebDriverWait類的until()方法進行靈活判斷 進行下一步操做
        # 經過EC進行判斷某個元素中是否可見而且是enable的 這樣的話叫clickable(可點擊)
        # 使用CSS選擇器選中頁面中的 首頁 進行點擊 目的爲了第一次有個登陸彈窗 刷新就沒有 那就點擊下首頁來實現刷新
        index.click() #點擊!

        input = WAIT.until(EC.presence_of_element_located((By.CSS_SELECTOR,'#banner_link > div > div > form > input'))) #判斷某個元素是否被加到DOM樹裏,並不表明該元素必定可見(元素能夠是隱藏的)
        submit = WAIT.until(EC.element_to_be_clickable((By.XPATH,'//*[@id="banner_link"]/div/div/form/button'))) #判斷搜索按鈕是否能點擊,這裏使用Xpath來尋找元素
        input.send_keys('蔡徐坤 籃球') #用send_keys()方法進行搜索輸入框中輸入內容
        submit.click() #點擊搜索!

        print('跳轉到新窗口')
        all_h = browser.window_handles #獲取全部窗口句柄
        browser.switch_to.window(all_h[1]) #switch_to.window 標籤頁跳轉

        get_source()
        total = WAIT.until(EC.presence_of_element_located((By.CSS_SELECTOR,"#server-search-app > div.contain > div.body-contain > div > div.page-wrap > div > ul > li.page-item.last > button"))) #等待加載後獲取全部頁數按鈕
        return int(total.text) #返回頁碼數量
    except TimeoutException:
        return seach()

def get_source():
    WAIT.until(EC.presence_of_element_located((By.CSS_SELECTOR,'#server-search-app > div.contain > div.body-contain > div > div.result-wrap.clearfix'))) #堅持是否加載完全部搜索結果
    html = browser.page_source #page_source方法能夠獲取到頁面源碼
    soup = BeautifulSoup(html,'lxml')
    save_to_excel(soup)

def save_to_excel(soup):
    #遍歷全部搜索信息 並保存
    list = soup.find(class_='all-contain').find_all(class_='info')
    for item in list:
        item_title = item.find('a').get('title')
        item_link = item.find('a').get('href')
        item_dec = item.find(class_='des hide').text
        item_view = item.find(class_='so-icon watch-num').text
        item_biubiu = item.find(class_='so-icon hide').text
        item_date = item.find(class_='so-icon time').text

        print('爬取:' + item_title)

        global n

        sheet.write(n, 0, item_title)
        sheet.write(n, 1, item_link)
        sheet.write(n, 2, item_dec)
        sheet.write(n, 3, item_view)
        sheet.write(n, 4, item_biubiu)
        sheet.write(n, 5, item_date)

        n = n + 1

def next_page(page_num):
    try:
        print('獲取下一頁數據')
        next_btn = WAIT.until(EC.element_to_be_clickable((By.CSS_SELECTOR, '#server-search-app > div.contain > div.body-contain > div > div.page-wrap > div > ul > li.page-item.next > button')))
        #等待加載 下一頁 按鈕
        next_btn.click() #點擊下一頁!
        WAIT.until(EC.text_to_be_present_in_element((By.CSS_SELECTOR,'#server-search-app > div.contain > div.body-contain > div > div.page-wrap > div > ul > li.page-item.active > button'),str(page_num)))
        #判斷某個元素中的text是否包含了預期的字符串
        get_source()

    except TimeoutException:
        browser.refresh() #刷新頁面
        return next_page(page_num)

def main():
    try:
        total = seach()

        for i in range(2,int(total+1)):
            next_page(i)

    finally:
        browser.close()
        browser.quit()

if __name__ == '__main__':
    main()
    book.save(u'蔡徐坤籃球.xls')  #在字符串前加r,聲明爲raw字符串,這樣就不會處理其中的轉義了。不然,可能會報錯
相關文章
相關標籤/搜索