python 之 爬蟲數據采集
爬蟲爬取數據的第一步必須分析目標網站的技術以及網站數據結構(通過前端源碼),可借助chrome瀏覽器,目前python爬蟲主要會面對一下三種網站:
- 前后端分離網站
前端通過傳遞參數訪問接口,后端返回json數據,對於此類網站,python可模擬瀏覽器前端,發送參數然后接收數據,便完成了爬蟲數據的目標 - 靜態網站
通過python的第三方庫(requests、urllib),下載源碼,通過xpath、正則匹配數據 - 動態網站
如果采用第2種方法,下載的源碼只是簡單的html,源碼中沒有任何數據,因為此類動態網站需要js加載后,源碼中才會有數據,對於此類網站,可以借助自動化測試工具selenium
爬蟲步驟:
- 分析網站技術與目標數據的結構
- 根據第一步分析結構,選擇對應的技術策略
- 爬取數據
- 提升性能,提高操作舒適度(結合客戶端技術,為爬蟲定制界面)
- 根據需求進行數據清洗
- 數據儲存,存儲到數據庫、文檔等
反扒機制:
- 當系統判斷同屬一個ip的客戶端不間斷多次訪問,會拒絕此ip的訪問
解決方案:動態代理,不停的更換ip去訪問目標系統,或者從免費的ip代理網站爬取ip,創建ip池,如果目標數據量不大,可通過降低訪問速度,以規避反扒 - 目標系統需要注冊登錄才能訪問
解決方案:通過python的第三方庫(Faker)生成假登錄名、密碼、個人數據進行自動化注冊、登錄 - 目標系統的中目標數據頁面的鏈接需要處理才能進入目標數據頁進行訪問
解決方案:獲取到目標網站的目標數據頁鏈接無法正常訪問,需要研究頁面中的js腳本,對鏈接進行處理,我個人曾通過搜狗瀏覽器爬取微信號文章時,就遇到過這個問題,爬取到的文章鏈接需要進過js腳本進行拼接,才能獲得正確的鏈接地址
獲取目標數據的位置:
通過xpath獲得數據的位置,可借助chrome瀏覽器調試功能獲得對應數據的xpath路徑
通過正則匹配
python爬蟲第三方常用庫:
urllib/requests 請求庫
Faker 生成假數據
UserAgent 生成假數據頭
etree、beautsoup 匹配數據
json 處理json數據
re 正則庫
selenium 自動化測試庫
sqlite3 數據庫 python3自帶
爬取靜態網頁數據:
import requests
from fake_useragent import UserAgent #提供假的請求頭
from lxml import etree # 匹配數據
#爬取目標頁面的url
url='http://***ip****:8085/pricePublic/house/public/index'
headers= {'User-Agent':str(UserAgent().random)}
response=requests.get(url,headers=headers)
# 獲得網頁源碼
content=response.text
html=etree.HTML(content)
#使用xpath查找對應標簽處的元素值,pageNum此處爬取對應頁面的頁碼
pageNum=html.xpath('//*[@id="dec"]/div[2]/div/span[1]/text()')
爬取前后端分離系統的數據:
import json
import requests
#獲取返回的response
url='http://***ip***/FindById/22'
response=requests.get(url)
#通過json庫解析json,獲得返回的數據
DataNode = json.loads(response.text).get('returndata').get('data')[0]
爬取動態數據:
以下代碼示例采用google瀏覽器,使用selenium庫,將瀏覽器設置為無頭模式,爬蟲會配合瀏覽器在后台模擬人工操作,根據代碼中定義的xpath地址,爬蟲會在瀏覽器中找到相應位置進行操作,使用selenium爬取數據時,需要安裝對應版本的瀏覽器驅動器
import requests
from faker import Faker
from fake_useragent import UserAgent
from lxml import etree
url='http://***ip***/FindById/22'
#通過faker庫獲得假email和電話號碼
fake=Fakeer('zh_CN')
email=fake.email()
tel=fake.phone_number()
data={
"email":email
}
#使用requests庫發送post請求
response=requests.post(url,data,headers=headers)
code=response.status_code
content=response.text
#獲得返回的cookies並轉換為字典形式
cookies = requests.utils.dict_from_cookiejar(response.cookies)
#請求的時候帶上cookies
response=requests.get(url,headers=headers,cookies=cookies)
