在爬取數據時,我們首先需要通過F12抓包觀看它的請求方式、響應數據格式與內容等,一般情況下,可以在響應數據中看到該頁面完整的內容,但有時存在其它情況,就是在刷新頁面后,發現抓取到的數據只是當前頁面的一部分數據,說明沒有展現出來的數據很可能是動態加載的,那么這種情況我們肯定不能直接對當前URL發出請求就能獲取的,本例就是這種情況。
該頁面抓取到的信息如下:
我們把其中響應數據粘貼出來:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>化妝品生產許可信息管理系統服務平台</title>
<meta http-equiv="keywords" content="化妝品生產許可信息管理系統服務平台,化妝品生產許可證查詢,化妝品生產許可企業查詢,化妝品生產許可企業"/>
<meta http-equiv="description" content="化妝品生產許可信息管理系統服務平台是由國家葯品監督管理局主辦,此平台可以查到化妝品生產企業信息"/>
<script language="javascript" type="text/javascript">
var G = {"baseUrl":"http://scxk.nmpa.gov.cn:81/xk/"}; </script>
<script src="http://scxk.nmpa.gov.cn:81/xk/itownet/_static/common/jquery/jquery-1.7.1.min.js" type="text/javascript" charset="utf-8"></script>
<script src="http://scxk.nmpa.gov.cn:81/xk/itownet/_static/common/jquery/plugins/jquery.cookie.js" type="text/javascript" charset="utf-8"></script>
<script src="http://scxk.nmpa.gov.cn:81/xk/itownet/portal/jquery.myPagination.js" type="text/javascript" charset="utf-8"></script>
<link rel="stylesheet" href="http://scxk.nmpa.gov.cn:81/xk/itownet/portal/style_portal.css" type="text/css" />
<link rel="stylesheet" href="http://scxk.nmpa.gov.cn:81/xk/itownet/_static/css/page.css" type="text/css" />
<script src="http://scxk.nmpa.gov.cn:81/xk/itownet/portal/portal.js?v=2017-01-15" type="text/javascript" charset="utf-8"></script>
</head>
<body >
<div class="hzbbanner"><div class="hzbbannertxt"><a href="http://scxk.nmpa.gov.cn:81/xk/itownet/allQyxx/allQyxx.jsp" target="_self" title="進入化妝品生產許可信息管理系統">【全部許可證】</a><a href="http://scxk.nmpa.gov.cn:81/xk/login.jsp" target="_blank" title="進入化妝品生產許可信息管理系統">【業務辦理】</a></div></div>
<div class="hzbscbox">
<div class="hzbscin">
<div style="position:relative;">
<div class="hzbtabs">
<span id="xkzh" class="hzbtabon" dataid="1">許可證編號</span>
<span id="qymc" dataid="2">企業名稱</span>
<span id="xydm" dataid="3">社會信用代碼</span>
<span id="sf" dataid="4">所屬省份</span>
<span id="lb" dataid="5">生產類別</span>
<input type="hidden" id="conditionType" value="1"/>
</div>
</div>
<input type="text" id="searchtext" class="hzbsr" name="kw" value="" placeholder="請輸入許可證號" />
<input type="button" class="hzbbtn" id="searchInfo" value="查詢" />
</div>
</div>
<div class="dzpzmain">
<div id="FileItems">
<ul class="hzblist" style="margin-top: 0px;margin-bottom: 0px;border-top: 0px;border-bottom: 0px;">
<li class="columm"><i>發證日期</i>
<dl>企業名稱 </dl>
<ol>許可證編號 </ol>
<p>發證機關</p> <em>有效期至</em>
</li>
</ul>
<ul class="hzblist" id="gzlist" style="margin-top: 0px;border-top: 0px;">
</ul>
</div>
<div id="itownetPage"></div>
</div>
<div class="hzbbtm"> 本站由<a href="http://www.sfda.gov.cn/WS01/CL0479/" target="_blank">國家葯品監督管理局</a>主辦 版權所有 未經許可禁止轉載或建立鏡像 Copyright © NMPA All Rights Reserved </div>
</body>
</html>
顯然,里面並沒有相關公司的具體數據,當我們再次刷新頁面,並選中XHR,會發現發送了一個新的POST請求(此時URL並沒有改變,說明存在ajax):
此外,我們發現返回的響應數據是多個列表存放在一個字典中,而且每個公司對應了一個ID屬性,接下來進入到具體的某個公司的詳情頁,同上操作會發現詳情頁中的數據仍然存在動態加載的數據:
因此,通過分析,我們可以得出結論:每個公司對應唯一的屬性值id,每次刷新時會根據id動態加載出對應公司的詳情頁,然后再把該詳情頁的URL以超鏈接的形式動態加載到首頁中,如此一來爬蟲程序就比較復雜了。
首先,我們要批量獲取ID值,因為有了ID才能找到對應的公司(順便實現分頁爬取功能):
for page in range(1,3): page = str(page) data = { 'on':' true', 'page':page, 'pageSize':' 15', 'productName':'', 'conditionType':' 1', 'applyname':'', 'applysn':'', } json_ids = requests.post(url=url,data=data,headers=headers).json() # print(json_ids)
# 從json_ids字典中取出list對應的value值(是個列表):json_ids['list'],然后遍歷該列表,拿到的每一部分都是個字典
for dic in json_ids['list']: # dic是每個小字典,里面含有ID等信息,我們只需要拿出ID對應的value值,然后把它添加到一個列表中id_list
# aaa.append(data):把數據data添加到鏈表aaa末尾
id_list.append(dic['ID']) # print(id_list)
此時,id_list中就已經存儲了前兩頁的企業對應的id,接下來一邊遍歷該列表,一邊模擬瀏覽器發送請求,最終可得到前兩頁所有企業的詳情數據:
post_url = 'http://scxk.nmpa.gov.cn:81/xk/itownet/portalAction.do?method=getXkzsById'
for id in id_list: data = { 'id':id } detail_json = requests.post(url=post_url,data=data,headers=headers).json() # print(detail_json)
all_data_list.append(detail_json)
最后,持久化存儲后,可成功爬取前兩頁企業的詳情數據:
至此,requests模塊暫時告一段落,接下來學習數據解析部分,先簡單介紹一下:
數據解析適用於聚焦爬蟲,用於爬取一整張頁面的局部數據,有三種方式:正則、bs4、Xpath。