動態網頁的抓取

在進行爬蟲的時候,有時候我們在網頁中看到的數據是一個樣子的,但是抓取到的數據卻是另外一個樣子的。這是爲什麼呢?這個時候啊很可能我們抓取的是動態網頁。動態網頁的代碼雖然沒有改變,但是顯示的內容卻是可以隨着時間、環境或者數據庫操作的結果二發生改變的。動態網頁一般使用被稱爲 AJAX 的快速動態創建網頁技術。通過在後臺與服務器進行少量數據交換,AJAX可以使網頁實現異步更新。那麼這種網頁該如何進行抓取呢?我們可以考慮使用如下兩種方法。

1. 分析頁面請求,查找真實請求的URL

既然 AJAX 技術是在後臺與服務器交換數據,只要有數據發送過來,就肯定有發送到服務器的請求,只需找出它加載出頁面的真實請求,然後構造併發送請求即可。

2. 使用Selenium模擬瀏覽器行爲

Selenium是一個自動化測試工具,被廣泛的用來做爬蟲,在爬蟲中主要使用Selenium解決動態網頁的加載和渲染功能。Selenium 可以用代碼模擬操作瀏覽器,模擬人的操作。可以使用 Selenium,配合 headless 的瀏覽器(如:phantomjs、headless Chrome)來加載和渲染網頁,然後提取需要的信息。

案例
1. 鏈家經紀人頁面分析

我們來對移動端的 鏈家經紀人頁面 進行分析,相比於 PC 端,移動端的網頁更爲簡單、簡潔。所以如果一個網頁有移動端的話,我們優先選擇移動端網頁進行爬取。打開網頁拉動滾動條,將其拉到底,添加一些數據進來,我們發現 NetWork 裏出現了很多的請求信息,這些請求大部分都是以 jpg 結束的圖片請求,但是我們仔細觀察,就能發現一項比較特殊的請求,如下:在這裏插入圖片描述
我們繼續滑動滾動條,又會發現類似的請求,我們將該請求鏈接複製出來,單獨打開,發現它是不同經紀人的請求頁面。我們對該鏈接進行分析,發現後面有一項 offset 的值一直在改變,而且每次以 15 增加,會請求到新的 15 條數據。因此你,我們只需要更改 offset 的值即可請求不同的頁面。至此,我們已經發現了該網站 URL 的構造規律了,下面就可以編寫代碼進行爬取了。

# -*- coding: utf-8 -*-
# # @Author: lemon
# # @Date:   2019-09-19 18:18
# # @Last Modified by:   lemon
# # @Last Modified time: 2019-09-19 18:42
# # @function: 爬取鏈家經紀人數據

import requests
import time
from lxml import etree
import pandas as pd

# 存儲 DataFrame 中用到的數據
data = {
    '姓名': [],
    '職位': [],
    '評分': []
}

def spider(list_url):
    headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/75.0.3770.100 Safari/537.36'
    }
    response = requests.get(list_url, headers=headers)
    time.sleep(5)
    sel = etree.HTML(response.text)
    # 先爬取每一位經紀人的整體代碼段
    agent_list = sel.xpath('//li[@class="pictext flexbox box_center_v lazyload_ulog"]')
    for agent in agent_list:
        agent_name = agent.xpath('div/div[2]/div[1]/span[1]/a/text()')[0].strip()           # 姓名
        agent_level = agent.xpath('div/div[2]/div[1]/span[2]/text()')[0].strip()            # 職位
        agent_score = agent.xpath('div/div[2]/div[1]/span[3]/span[1]/text()')[0].strip()    # 評分

        print(agent_name, agent_level, agent_score)

        data['姓名'].append(agent_name)
        data['職位'].append(agent_level)
        data['評分'].append(agent_score)


def write_data(data):
    frame = pd.DataFrame(data)
    frame.to_excel('鏈家經紀人數據.xlsx')

if __name__ == '__main__':
    for i in range(10):
        # 根據加載的時候 offset 的變化規律, 構造不同頁面的 URL
        url = 'https://m.lianjia.com/cs/jingjiren/?page_size=15&_t=1&offset=' + str(i * 15)
        print(f'正在爬取 page {i + 1}...')
        spider(url)

    write_data(data)

這是我們最終爬取到的經紀人數據:
在這裏插入圖片描述

2. Selenium 請求百度

由於 Selenium 不是 Python 的標準庫,因此我們首先需要安裝 Selenium 庫。

pip install selenium

Selenium 需要使用 chromedriver 來驅動 Chrome 瀏覽器,我們需要下載與操作系統對應的版本,可參考 ChromeDriver與Chrome版本對應參照表及ChromeDriver下載鏈接 進行下載安裝。
Selenium 在使用 chromedriver 時,既可以把 chromedriver添加到系統的環境變量中,也可以直接在代碼中指明 chromedriver 所在的目錄。

下面我們使用 Selenium 訪問百度首頁

# -*- coding: utf-8 -*-
# # @Author: lemon
# # @Date:   2019-09-19 19:00
# # @Last Modified by:   lemon
# # @Last Modified time: 2019-09-19 19:10
# # @function: Selenium 打開百度


# %%1 從 selenium 中引入 webdriver
from selenium import webdriver

driver = webdriver.Chrome('E:\ChromeDriver\chromedriver.exe')   # 初始化 webdriver
driver.get('https://www.baidu.com/')                            # 使用 webdriver 打開百度首頁
search_box = driver.find_element_by_xpath('//*[@id="kw"]')      # 使用 xpath 找到搜索框
search_box.send_keys('python')                                  # 在搜索框中搜索關鍵字
submit = driver.find_element_by_xpath('//*[@id="su"]')          # 使用 xpath 找到搜索按鈕
submit.click()                                                  # 點擊搜索按鈕進行搜索

可觀察到如下效果:我們的 Chrome 瀏覽器正在收到自動測試軟件的控制
在這裏插入圖片描述
後續的文章我們爲大家示例:如何使用 Selenium 爬取新浪微博的網站,進一步加強大家對於 Selenium 的使用。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章