1. Ajax 介紹
Ajax 即“Asynchronous Javascript And XML”(異步 JavaScript 和 XML),是指一種創建交互式、快速動態網頁應用的網頁開發技術,無需重新加載整個網頁的情況下,能夠更新部分網頁的技術。
通過在後臺與服務器進行少量數據交換,Ajax 可以使網頁實現異步更新。這意味着可以在不重新加載整個網頁的情況下,對網頁的某部分進行更新。(百度百科),網易新聞的頁面就屬於這一類,如下,只要一直往下拉,新聞就會一直出現
2. 爬取邏輯
【找到新聞資訊所在位置】 -> 【確定資源的url】 -> 【獲取json數據】 -> 【按需求獲取數據並存入數據庫或者保存本地】
針對爬取邏輯封裝兩個函數:
1) 獲取資源url的函數
def get_url(n)
:
n
:爬取數據的頁數
return
返回值: json數據對應url的列表
2) 獲取需求數據並存入數據庫
def get_data(url,dic_h,table)
:
url
:json數據對應的url
dic_h
:請求頭
table
:數據庫表格
return
返回值:數據爬取量計數
3. 資源url獲取
1) 解析json數據文件
首先解析一下網易新聞的頁面,在某一新聞頁面(比如這裏選擇的就是’要聞’界面),右鍵檢查,進行測試,和之前獲取headers和cookies的操作步驟類似,尋找json數據接口
操作如下:【右鍵進入檢查界面】-> 【選中菜單欄Network】-> 【點擊刷新按鈕】-> 【查找右下角中的文件】-> 【找到包含json數據的文件】-> 【下拉左側原界面】-> 【按規律找到全部包含json數據的文件】
圖解如下:(因爲找到包含json數據的文件是cm_開頭的,所以爲了過濾掉其他的信息文件,這裏直接就只查看所有包含json數據的文件,可以看出沒刷新一次頁面就會有一個callback文件出現在Name欄下面)
2) 確定json文件對應的url
在上面的步驟的基礎上,點擊Preview左側的Headers,其中Request URL後面的內容就是json數據對應的url了,對應如下
u1 = https://temp.163.com/special/00804KVA/cm_yaowen20200213.js?callback=data_callback
u2 = https://temp.163.com/special/00804KVA/cm_yaowen20200213_02.js?callback=data_callback
u3 = https://temp.163.com/special/00804KVA/cm_yaowen20200213_03.js?callback=data_callback
u4 = https://temp.163.com/special/00804KVA/cm_yaowen20200213_04.js?callback=data_callback
u5 = https://temp.163.com/special/00804KVA/cm_yaowen20200213_05.js?callback=data_callback
這裏列舉了前五頁的url,是不是就像最初爬取網頁那樣也類似的規律呢,也就是第一頁的url是可以寫成xxx20200213_01.js?xxx類似的格式呢?可以嘗試一下,在瀏覽器界面輸入下面這個網址,看看是否真的有規律可循,如下
https://temp.163.com/special/00804KVA/cm_yaowen20200213_01.js?callback=data_callback
–> 輸出結果爲:(按照相同的方式,發現其他的網頁都可以按照原網址進行打開,也就是說這裏的首頁的url是不符合之前爬蟲的網頁的規律的,因此需要單獨進行判斷)
3) 封裝第一個函數,返回url列表
def get_url(n):
urllst = []
url_fixed = 'https://temp.163.com/special/00804KVA/cm_yaowen20200213.js?callback=data_callback'
urllst.append(url_fixed)
urllst.extend([f'https://temp.163.com/special/00804KVA/cm_yaowen20200213_0{i}.js?callback=data_callback' for i in range(2,n+1)])
# for i in range(2,n+1):
# urllst.append(f'https://temp.163.com/special/00804KVA/cm_yaowen20200213_0{i}.js?callback=data_callback')
return urllst
get_url(5)
–> 輸出結果爲:(對比可以發現這五條數據和在網頁上找的url是一致的,在瀏覽器界面打開後均有數據返回)
['https://temp.163.com/special/00804KVA/cm_yaowen20200213.js?callback=data_callback',
'https://temp.163.com/special/00804KVA/cm_yaowen20200213_02.js?callback=data_callback',
'https://temp.163.com/special/00804KVA/cm_yaowen20200213_03.js?callback=data_callback',
'https://temp.163.com/special/00804KVA/cm_yaowen20200213_04.js?callback=data_callback',
'https://temp.163.com/special/00804KVA/cm_yaowen20200213_05.js?callback=data_callback']
5. 需求數據的爬取並將數據存入數據庫
1) 先配置數據庫參數
這裏使用mongo數據庫作爲數據存儲,比較簡單便捷,總共只需要四行代碼就配置好數據庫,關於mongo數據庫的安裝可以查看mongo快速入門
#導入數據庫模塊
import pymongo
# 鏈接上服務器
myclient = pymongo.MongoClient("mongodb://localhost:27017/")
#創建一個數據庫
db = myclient['騰訊新聞']
#在該數據庫下創建一個'表格'保存數據
table = db['data1']
2) 數據爬取試錯
在進行大量數據爬取之前,先測試一下能否進行某一頁的信息數據的獲取,如果沒有問題了再進行下一步操作,這樣就可以避免出現問題後再回過頭來查找錯誤,節省時間。
在將數據清洗爲json可轉化的數據類型過程中,要查找位置索引的問題,在之前的python爬取酷狗音樂中已經介紹過,下面直接給出代碼
def get_data(url,dic_h,table):
count = 0
ri = requests.get(url,headers = dic_h)
start = ri.text.index('[')
end = ri.text.index('])') + 1
datas = json.loads(ri.text[start:end])
return datas
urllst = get_url(5)
dic_h = {'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'}
get_data(urllst[0],dic_h,table)
–> 輸出結果爲:(這裏以第一個url進行試錯,查看是否可以成功的返回請求的數據,只截取其中的一條信息)
3) 獲取需求字段信息
在試錯無誤後就可以或許需求的字段信息了,其中關於keywords字段信息的獲取這裏可以講一下,通過上面的輸出圖片可以發現,所有的信息都是以鍵值對的形式存儲,其他的字段信息都是爲字符串,而keywords字段信息是列表中嵌套着字典,因此要提取出裏面的keyname信息,還是需要點技巧的,代碼如下
for data in datas:
dic = {}
dic['title'] = data['title']
dic['docurl'] = data['docurl']
dic['commenturl'] = data['commenturl']
dic['source'] = data['source']
dic['time'] = data['time'].split(' ')[0]
dic['keywords'] = ','.join(x['keyname'] for x in data['keywords'])
count += 1
#table.insert_one(dic)
print(dic)
–> 輸出結果爲:(時間字段進行空格分隔,只選擇年月日即可,其他的字段直接可以選取,keywords字段信息需要先遍歷表格然後取出裏面的keyname信息,再將信息以逗號的形式組成字符串,這樣所有需要的字段信息都獲取完畢了,也可以添加一些其他的字段爬取信息,未防止審覈不通過,下面只截取部分結果)
4) 獲取全部數據並保存在數據庫
數據插入數據庫的操作就是一條指令table.insert_one(dic)
,打開上面的註釋即可,最後進行url的遍歷循環即可,爲了防止出錯,可以加上try-except進行異常處理
error_lst = []
count = 0
for u in urllst:
try:
count += get_data(urllst[0],dic_h,table)
print(f'成功爬取並存儲{count}條數據')
except :
print('未能爬取數據網址爲:',u)
error_lst.append(u)
6. 全部代碼及運行結果
如果要將結果數據
import pymongo
#import pandas as pd
import json,requests
def get_url(n):
urllst = []
url_fixed = 'https://temp.163.com/special/00804KVA/cm_yaowen20200213.js?callback=data_callback'
urllst.append(url_fixed)
urllst.extend([f'https://temp.163.com/special/00804KVA/cm_yaowen20200213_0{i}.js?callback=data_callback' for i in range(2,n+1)])
# for i in range(2,n+1):
# urllst.append(f'https://temp.163.com/special/00804KVA/cm_yaowen20200213_0{i}.js?callback=data_callback')
return urllst
get_url(5)
def get_data(url,dic_h,table):
n = 0
ri = requests.get(url,headers = dic_h)
start = ri.text.index('[')
end = ri.text.index('])') + 1
datas = json.loads(ri.text[start:end])
#data_lst = []
for data in datas:
dic = {}
dic['title'] = data['title']
dic['docurl'] = data['docurl']
dic['commenturl'] = data['commenturl']
dic['source'] = data['source']
dic['time'] = data['time'].split(' ')[0]
dic['keywords'] = ','.join(x['keyname'] for x in data['keywords'])
table.insert_one(dic)
n += 1
#print(dic)
#data_lst.append(dic)
return n
if __name__ == '__main__':
myclient = pymongo.MongoClient("mongodb://localhost:27017/")
db = myclient['網易新聞']
table = db['data1']
urllst = get_url(5)
dic_h = {'user-agent': 'Mozilla/5.0'}
error_lst = []
count = 0
for u in urllst:
try:
count += get_data(urllst[0],dic_h,table)
print(f'成功爬取並存儲{count}條數據')
except :
print('未能爬取數據網址爲:',u)
error_lst.append(u)
–> 輸出結果爲:
生成桌面的文件如下:(截取部分)