Python爬取加載js的頁面


Python爬取便民查詢網的飛機場信息

思路:查看網頁源碼可以看出,289個頁面按鈕的的URL的規律很明顯

頁碼按鈕的鏈接


可以將這些URL寫入一個test.txt文件。對於每一頁面根據HTML可以看出,找到table標簽下的table標簽,該table標簽下的所有a標簽就是機場詳細信息的鏈接

頁面上機場詳細信息的鏈接


進入機場的詳細信息頁面,查看源碼,發現規律也很強,在table的table下的tbody有機場的詳細信息。tr下的兩個td有對應信息的屬性和值,很容易取出。

機場詳細信息頁面


總體思路就是:將所有頁碼鏈接的URL存入test.txt文件,每次讀取一個頁面的URL(一行)訪問,將該頁面上的機場鏈接提取出來存入列表,分別訪問列表中的機場詳細信息URL,從中提取出機場詳細信息

由於某些機場的詳細信息頁面源碼提供的信息並不正確,需要執行js腳本后才能得到正確的信息。因此選擇selenium+phantomjs組合爬取頁面(selenium是一個測試工具,phantomjs是一個無界面瀏覽器,selenium通過打開phantomjs.exe加載phantomjs瀏覽器),可以獲取加載js后的HTML頁面


代碼如下

import requests  # 發請求的庫
from bs4 import BeautifulSoup  # 解析HTML的庫
import json
import time
from selenium import webdriver  # 加載瀏覽器的庫

airportInfoList = []  # 保存所有機場詳細信息的列表,元素是字典

siteURL = "https://airportcode.51240.com"  # 網站資源URL的共同前綴


def getAirportInfo(PageURL, page):  # 獲取每個頁面的機場列表

    try:  # 設置異常處理可以在爬取異常時,將已經爬取的內容寫入文件
        browser = webdriver.PhantomJS(executable_path=r'C:\phantomjs\bin\phantomjs')  # 加載瀏覽器

        response = requests.get(PageURL)  # requests請求網頁,這個只是獲取機場的URL列表,不需要加載js,直接requests請求
        response.raise_for_status()  # 出錯拋異常
        response.encoding = response.apparent_encoding
        html = response.text
        soup = BeautifulSoup(html, 'html.parser')  # 解析html文件
        tag_as = soup.table.table.find_all('a')
        length = str(len(tag_as))
        i = 1
        for tag_a in tag_as:
            airportDetailURL = siteURL + tag_a.attrs['href']
            print("第:" + str(page) + "/298 個頁面的第:" + str(i) + "/" + length + "個機場")
            getAirportDetailInfo(airportDetailURL, browser)  # 爬取一個機場的詳細信息
            i = i + 1

        # 關閉瀏覽器,瀏覽器每爬取一個頁面上的所有機場后重啟一次
        # 這是因為如果不關閉瀏覽器,連續訪問頁面,會導致內存占用增加(雖然只是在一個標簽頁里請求資源)
        # 我嘗試過打開新的標簽頁,刪除舊的標簽,在新的標簽頁里請求資源,但內存還是會增加,只是增加的速度慢了
        # 把瀏覽器關了重啟是最穩妥的方法了
        # 總共有8662個頁面,如果連續爬取,會把內存撐爆的
        browser.quit()
    except:
        print("從 " + PageURL + "獲取數據失敗")
        browser.quit()
        return 0


def getAirportDetailInfo(airportDetailURL, browser):  # 從獲取的機場列表中獲取每個機場的詳細信息

    try:
        time.sleep(3)  # 間隔3秒訪問一次,訪問服務器速度太快會被禁的,設置為1秒或2秒會在訪問100多個頁面后被禁
        browser.get(airportDetailURL)  # 瀏覽器請求頁面
        html = browser.page_source
        soup = BeautifulSoup(html, 'html.parser')
        tag_trs = soup.table.table.find_all('tr')
        airportInfoDict = {}
        for tr in tag_trs:
            airportInfoDict[tr.td.string] = tr.td.next_sibling.next_sibling.span.string

        airportInfoList.append(airportInfoDict)
    except:
        print("從 " + airportDetailURL + "獲取數據失敗")
        return 0


def writeInfoToFile(infoFilepath):

    with open(infoFilepath, 'w+', encoding='utf-8') as infoFile:
        infoFile.write(json.dumps(airportInfoList, ensure_ascii=False))


def main():  # 讀取機場URL文件,獲取機場列表
    infoFilePath = "test.json"
    page = 1  # 打印爬取進度用,爬取程序很漫長的,沒有提示信息很恐怖的

    with open("test.txt", 'r') as AirportFile:
        for PageURL in AirportFile:
            print("第:" + str(page) + "/298 個頁面")
            getAirportInfo(PageURL, page)  # 獲取一個頁面中所有機場詳細信息
            page = page + 1

    writeInfoToFile(infoFilePath)  # 將機場詳細信息列表里的數據寫入json文件


if __name__ == '__main__':
    main()


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM