在 <em>Python</em> 中,可以使用 urllib.parse.quote() 得到,即 '%E5%BE%AE%E4%BF%A1' = urllib.parse.quote('微信')。 按照标准,URL 中只允许包含英文字母、数字以及部分符号,其他字符(比如中文)是
2021-05-29 10:00:18
1.1 Ajax 非同步載入生成網頁內容
現在越來越多的網頁使用 Ajax 非同步載入方式,即網頁中的一些內容由前端的 JS 動態生成。由於呈現在網頁上的內容是由 JS 生成而來,我們能夠在瀏覽器上看到,但是在 HTML 源碼中卻發現不了。
比如應用寶的搜尋應用頁面,顯示如下:
從上面可以看到,搜尋出來的應用列表資訊是在 id="J_SearchDefaultListBox" DOM 樹下面。
檢視當前網頁的源碼(使用快捷鍵 「Ctrl + U」)如下:
在源碼中,發現元素 id="J_SearchDefaultListBox" 下面的內容為空,沒有任何應用列表資訊。
通過上面的分析可知,應用寶應用搜索頁面中顯示的應用列表是由 JS 動態生成載入的。
遇到這種情況,我們應該如何對網頁內容進行爬取呢?一般有兩種方法:
(1)從網頁響應中找到 JS 指令碼返回的資料(大多是 json 格式,也有 xml 格式。);
(2)使用 Selenium 對網頁進行模擬訪問。
下面我們將介紹第一種方法。第二種方法可以參考這裡。
1.2 從網頁響應中找到 JS 指令碼返回的資料 既然網頁內容是由 JS 動態生成載入的,那麼 JS 就需要先對某個介面進行呼叫,然後根據介面返回的資料再進行載入和渲染。那我們可以先找到 JS 呼叫的資料介面,從資料介面中找到網頁中最後呈現的資料。 下面我們就以應用寶的搜尋應用頁面為例,進行說明。
1.2.1 找到 JS 請求的資料介面
按照如下步驟進行操作:
開啟應用寶的搜尋頁面(https://android.myapp.com/myapp/search.htm)按 F12 開啟網頁偵錯工具選擇 「Network」 選項卡選擇 「XHR」(即 XMLHTTPRequest,是 Ajax(Asynchronous JavaScript and XML,非同步的 JavaScript 和 XML) 中的概念。 )輸入應用名(例如:微信)將看到如下資訊:
在這裡,我們看到只有一個 request(其他網頁可能會存在多個)。點選這個 request,然後選擇 「Preview」,可以看到如下資料:
在上面的資料中,我們發現了「微信」、「多開助手」等資訊,這些就是搜尋出來的應用列表資訊。
通過上面的分析,可以知道搜尋出來的應用列表資訊正是通過這個 request 獲取的。這個 request 對應 URL 為 https://android.myapp.com/myapp/searchAjax.htm?kw=%E5%BE%AE%E4%BF%A1&pns=&sid=(獲取方法:將滑鼠移動到這個 request 上 -> 然後右鍵單擊 -> Copy -> Copy link address)。
將上面的 URL 在瀏覽器中開啟,會返回一串資料。看起來似乎很亂,但實際上是 JSON 格式的資料。
這樣,我們就找到了 JS 請求的資料介面。
1.2.2 URL 編碼 上面我們找到的 JS 請求的資料介面是 https://android.myapp.com/myapp/searchAjax.htm?kw=%E5%BE%AE%E4%BF%A1&pns=&sid=,但是其中的 %E5%BE%AE%E4%BF%A1 代表什麼意思呢?
實際上 %E5%BE%AE%E4%BF%A1 是中文 微信 的 URL 編碼。在 Python 中,可以使用 urllib.parse.quote() 得到,即 '%E5%BE%AE%E4%BF%A1' = urllib.parse.quote('微信')。
按照標準,URL 中只允許包含英文字母、數字以及部分符號,其他字元(比如中文)是不符合 URL 標準的。這個時候就需要進行 URL 編碼。
1.2.3 程式碼實現
按照以下 4 步進行實現:
(1)引入相關的庫;
(2)對 JS 請求的資料介面進行請求;
(3)對 HTTP 響應的資料進行 json 格式化;
(4)進行遍歷獲取列表中 App 的資訊(App 名稱、包名、版本號、apk 下載 URL等)
import jsonimport requestsfrom urllib.parse import quote# 對資料介面進行 http 請求app_name = '微信'url = 'https://android.myapp.com/myapp/searchAjax.htm?kw={}&pns=&sid=' .format(quote(app_name))web_data = requests.get(url).text# 對 http 響應的資料進行 json 格式化data = json.loads(web_data)app_infos = data['obj']['appDetails']# 進行遍歷獲取列表中 App 的資訊(App 名稱、包名、版本號、apk 下載 URL等)for app_info in app_infos: app_name = app_info['appName'] pkg_name = app_info['pkgName'] version_code = app_info['versionCode'] version_name = app_info['versionName'] download_url = app_info['apkUrl'] print(app_name, pkg_name, version_code, version_name, download_url)
近期有很多朋友通過私信諮詢有關Python學習問題。為便於交流,點選藍色自己加入討論解答資源基地
相關文章
在 <em>Python</em> 中,可以使用 urllib.parse.quote() 得到,即 '%E5%BE%AE%E4%BF%A1' = urllib.parse.quote('微信')。 按照标准,URL 中只允许包含英文字母、数字以及部分符号,其他字符(比如中文)是
2021-05-29 10:00:18
世界上开源的软件很多,操作系统开源的有Linux系统、安卓系统等(本质上都是Unix系统),甚至个别编程语言的解释器都是开源的,如<em>Python</em>。可是,开源不意味着平等,华为鸿蒙系统的确是开源的,可友商一旦接入,身家
2021-05-29 10:00:06
2011年 9 月三星携手<em>英特尔</em>共同开发针对手机和其它设备的操作系统,并于2012年2月正式发布。可当时市场已被安卓、iOS占领,基本上也没什么厂商愿意用它,单靠三星自己能力有限,而安卓也越来越完善,所以三星也
2021-05-29 09:31:02
除了处理器之外,锐龙版与之前的<em>英特尔</em>版没有太多区别。 So,直接进入价格环节。 RedmiBook Pro 14 锐龙版:R5 5500U 版本 4299 元;R7 5700U 版本 4699 元。 RedmiBook Pro 15 锐龙版:R5 5600H 版本 4799 元;R
2021-05-29 09:30:51
答案是两个,就是<em>高通</em>和联发科。 从IC Insights统计的2021年Q1市场数据中,包括海思在内,共有两家公司跌出前15名,另一家是索尼,而顶替它们上位的正是联发科和AMD。 从统计数据来看,联发科在2021年第一季度的
2021-05-29 09:30:42
这个时候需要一门网页脚本语言,这种脚本语言能够完成一些简单的操作,比如判断用户有没有填写表单。刚好这个时候是向对象编程(object-oriented programming)最兴盛的时期,C++是当时最流行的语言,而<em>Java</em>语言也马
2021-05-29 09:30:16