爬蟲入門到精通_實戰篇8(分析Ajax請求并抓取今日頭條美食美圖)_界面上抓取Ajax方式

1 目標

目標:
抓取今日頭條美食美圖,如下:
在這里插入圖片描述
一些網頁直接請求得到的HTML代碼并沒有在網頁中看到的內容,因為一些信息是通過Ajax加載,并通過js渲染生成的,這時就需要通過分析網頁的請求來獲取想要爬取的內容。

直接請求得到的HTML代碼并沒有在網頁中看到的內容:
在這里插入圖片描述
右擊空白處->審查->Network->勾選Preserve log->刷新網頁:
點擊XHR,再選中一個URL,查看請求的方法,發現是用get方法,所以使用requests庫。
在這里插入圖片描述
向下更新的過程中,作出url不斷更新:
在這里插入圖片描述
分析查找圖集詳細頁的代碼,來找到圖片的url,這個圖片url隱藏的比較深,都在JS代碼中:
在這里插入圖片描述
變量并不是在html代碼里的,所以不能使用BeautifulSoup和PyQuery來解析了,只能通過正則表達式來解析。

2 流程框架

  1. 抓取索引頁內容:利用requests請求目標戰點,得到索引頁面HTML代碼,返回結果。
  2. 抓取詳情頁內容:解析返回結果,得到詳情頁的鏈接,并進一步抓取詳情頁的信息。
  3. 下載圖片與保存數據庫:將圖片下載到本地,并把頁面信息及圖片URL保存至MongoDB。
  4. 開啟循環及多線程:對多頁內容遍歷,開啟多線程提取抓取速度。

3 實戰

1 抓取索引頁內容

看一下索引頁的請求方式:
在這里插入圖片描述
街拍界面更新了方式,了解了Ajax就行,后面寫法同上一章相似,暫時不仔細研究。
舊版形式的詳情。

4 整體代碼

import  requests
from urllib.parse import urlencode
from requests.exceptions import RequestException
import json
from bs4 import BeautifulSoup
import re
from config import *
import  pymongo
import os
from hashlib import md5
from multiprocessing import Pool
from json.decoder import JSONDecodeError
from pathlib import Pathheaders = {'User-Agent':'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36'}
#聲明mongodb數據庫對象
client = pymongo.MongoClient(MONGO_URL,connect=False)
db = client[MONGO_DB]#請求索引頁(索引頁中包含著許多圖集的url)
def get_page_index(offset,keyword):data = {#定義一個data字典,用于Ajax請求'offset': offset,'format': 'json','keyword': keyword,'autoload': 'true','count': '20','cur_tab': '3','from': 'gallery'}url='http://www.toutiao.com/search_content/?'+urlencode(data)try:response = requests.get(url,headers=headers)if response.status_code == 200:return response.textreturn Noneexcept RequestException:print('請求索引頁出錯')return None#傳入索引頁的html,解析出每個圖集的url
def parse_page_index(html):try:#加入異常處理data = json.loads(html)#對html進行解析,轉換為字典。if data and 'data' in data.keys():#data.keys()返回的是這個json的所有的鍵名,這里判斷'data'在這些鍵名中for item in data.get('data'):#data對應還有許多值,遍歷這些值yield item.get('article_url')#構造一個生成器,取出data中的每一個article_url對應的urlexcept JSONDecodeError:pass#請求每個圖集的詳情頁
def get_page_detail(url):try:response = requests.get(url,headers=headers)if response.status_code == 200:return response.textreturn Noneexcept RequestException:print('請求詳情頁出錯',url)return None#解析詳情頁,獲取圖集中每張圖片的url
def parse_page_detail(html,url):soup = BeautifulSoup(html, 'lxml')# 用BeautifulSoup來提取title信息title = soup.select('title')[0].get_text()print(title)#下面提取json串,串中包含了圖片信息images_pattern = re.compile('JSON.parse\("(.*?)"\),', re.S)#注意對括號進行轉義result=re.search(images_pattern,html)if result:result = result.group(1).replace('\\', '')data = json.loads(result)#轉換成json對象if data and 'sub_images' in data.keys():sub_images = data.get('sub_images')#每個sub_images都是一個字典,需要遍歷它來提取url元素# 用一句話來構造一個list,把item賦值為sub_images的每一個子元素# 再取得sub_images的每一個item對象的url屬性,完成列表的構建,這個列表名為images,里面是sub_images下所有的urlimages = [item.get('url') for item in sub_images]root_dir=create_dir('E:\spider\jiepai')download_dir = create_dir(root_dir/title)for image in images: download_image(download_dir,image)#通過循環把圖片下載下來return {#以一個字典形式返回'title':title,'url':url,#這是當前詳情頁的url'images':images}#把url存儲到數據庫
def save_to_mongo(result):if db[MONGO_TABLE].insert(result):print('存儲到MongoDB成功',result)return  Truereturn False#通過url來請求圖片
def download_image(save_dir,url):print('正在下載',url)try:response = requests.get(url,headers=headers)if response.status_code == 200:save_image(save_dir,response.content)#content返回的是二進制內容,一般處理圖片都用二進制流return response.textreturn Noneexcept RequestException:print('請求圖片出錯',url)return Nonedef create_dir(name):#根據傳入的目錄名創建一個目錄,這里用到了 python3.4 引入的 pathlib 。directory = Path(name)if not directory.exists():directory.mkdir()return directorydef save_image(save_dir,content):file_path = '{0}/{1}.{2}'.format(save_dir,md5(content).hexdigest(),'jpg')if not os.path.exists(file_path):#如果文件不存在with open(file_path,'wb') as f :f.write(content)f.close()def main(offset):html=get_page_index(offset, KEYWORD)for url in parse_page_index(html):#獲得每個圖集的urlhtml=get_page_detail(url)#用某個圖集的url來請求詳情頁if html:result=parse_page_detail(html,url)#解析詳情頁的信息if result:save_to_mongo(result)if __name__ == '__main__':groups = [x*20 for x in range(GROUP_START,GROUP_END+1)]#20,40,60...pool=Pool()pool.map(main,groups)

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/714641.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/714641.shtml
英文地址,請注明出處:http://en.pswp.cn/news/714641.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

解決conda環境下import TensorFlow失敗的問題

問題描述 安裝了anaconda的電腦,新建了一個名叫deeplearning的環境,在該環境下已經成功安裝了tensorflow。 于是在終端打開python并執行代碼 import tensorflow as tf print(1)除了提示 2024-02-27 21:50:00.801427: I external/local_tsl/tsl/cuda/c…

CSS 盒子模型(box model)

概念 所有HTML元素可以看作盒子,在CSS中,"box model"這一術語是用來設計和布局時使用CSS盒模型本質上是一個盒子,封裝周圍的HTML元素,它包括:外邊距(margin),邊框(border),內邊距(pad…

關于 HTTP 協議,你了解多少

HTTP協議 FastAPI 是建立在 HTTP 協議之上,所以為了更好的掌握 FastAPI。我們需要先簡單的了解一下 HTTP協議 簡介 HTTP(Hypertext Transfer Protocol)遵循經典的客戶端-服務器模型,客戶端打開連接以發出請求,然后等…

【Go語言】Go語言中的流程控制

Go語言中的流程控制 流程控制主要用于設定計算執行的順序,簡歷程序的邏輯結果,Go語言的流程控制語句與其他語言類似,支持如下幾種流程控制語句: 條件語句:用于條件判斷,對應的關鍵字有if、else和else if&a…

SQL 語句的執行順序

數據庫引擎在執行SQL語句并不是從SELECT開始執行,而是從FROM開始,執行順序如下(關鍵字前面的數字代表SQL執行的順序步驟): ⑧SELECT ⑨DISTINCT ⑩①【Top Num】 【select list】 ①FROM {left_table_name} ③【join_type】 JOIN {righ…

vuecli配置sass

vuecli5如何配置sass sass有很多優勢,可以減少css重復,提高效率等,本人使用了 vuecli5 node -v 查看node版本根據版本安裝node-sass sass-loader 如我的版本“node-sass”: “^4.14.1”,“sass-loader”: “^7.1.0”,node -vv14.15.0&#…

使用 Docker 部署 Fiora 在線聊天室平臺

一、Fiora 介紹 Fiora 簡介 Fiora 是一款開源免費的在線聊天系統。 GitHub:https://github.com/yinxin630/fiora Fiora 功能 注冊賬號并登錄,可以長久保存你的數據加入現有群組或者創建自己的群組,來和大家交流和任意人私聊,并添…

MySQL 主從讀寫分離入門——基本原理以及ProxySQL的簡單使用

一、讀寫分離工作原理 讀寫分離的工作原理:在大型網站業務中,當單臺數據庫無法滿足并發需求時,通過主從同步方式同步數據。設置一臺主服務器負責增、刪、改,多臺從服務器負責查詢,從服務器從主服務器同步數據以保持一…

C語言數據結構——隊列

目錄 0.前言 1.隊列的基本概念 2.隊列的實現 2.1實現方式 2.2具體實現 3.隊列的應用場景 4.一道隊列的算法題(LeetCode225. 用隊列實現棧) 5.結語 (圖像由AI生成) 0.前言 在計算機科學領域,數據結構是組織和…

Linux篇: 進程控制

一、進程創建 1.1 fork函數初識 在Linux中,fork函數是非常重要的函數,它從已存在進程中創建一個新進程。新進程為子進程,而原進程為父進程。 返回值: 在子進程中返回0,父進程中返回子進程的PID,子進程創…

OSI七層模型/TCP四層模型

協議: 協議是雙方共同指定的一組規則,在網絡通信中表示通信雙方傳遞數據和解釋數據的一組規則。 從A上傳文件到服務器B,需要在A和B之間制定一個雙方都認可的規則,這個規則就叫文件傳輸協議,該協議是ftp協議的一個初級版本&#…

LeetCode 刷題 [C++] 第226題.翻轉二叉樹

題目描述 給你一棵二叉樹的根節點 root ,翻轉這棵二叉樹,并返回其根節點。 題目分析 深度優先搜索(DFS)- 遞歸方式 對于二叉樹的鏡像問題,很容易想到的就是使用遞歸來解決,自底向上依次翻轉每一個節點…

2024年騰訊云優惠券領取頁面_代金券使用方法_新老用戶均可

騰訊云代金券領取渠道有哪些?騰訊云官網可以領取、官方媒體賬號可以領取代金券、完成任務可以領取代金券,大家也可以在騰訊云百科蹲守代金券,因為騰訊云代金券領取渠道比較分散,騰訊云百科txybk.com專注匯總優惠代金券領取頁面&am…

『大模型筆記』Sora:探索大型視覺模型的前世今生、技術內核及未來趨勢

Sora:探索大型視覺模型的前世今生、技術內核及未來趨勢 文章目錄 一. 摘要二. 引言楊立昆推薦的關于世界模型的真正含義(或應該是什么)的好文章。原文:Sora: A Review on Background, Technology, Limitations, and Opportunities of Large Vision Models譯文:Sora探索大型…

百度SEO快排原理是什么?如何快速排名方法?

前言:我之前說過我不打算寫這個快速排序。 首先,我從來沒有在自己的網站上操作過所謂的快速排序。 其次,我不能像網上很多人寫的那樣透露百度快速排序的秘密(說實話,你可以透露秘密)。 方法是有了&#xff…

Linux系統運維腳本:編寫bash腳本程序監控服務器的磁盤空間,在磁盤使用率超過閾值時發送警告郵件

目 錄 一、要求 二、解決方案 (一)解決思路 (二)方案 三、腳本程序實現 (一)腳本代碼和解釋 1、腳本代碼 2、代碼解釋 (二)腳本驗證 1、腳本編輯 2、給予執…

使用遞歸求解數組最大值(c++題解)

題目描述 輸入一個整數n(n不大于1000),接下來分別為n個整數,請使用遞歸求取最大值。 輸入格式 第一行:正整數n。 第二行:n個整數。 輸出格式 輸出最大值 樣例 樣例輸入 復制2 1 2樣例輸出 復制2 …

Postman: 前端必備工具還是后端獨享利器

Postman 的使用場景:適用于前端和后端 Postman 是一個流行的 API 測試與開發工具。它被廣泛地應用在前后端開發的過程中,但是很多人對于它的使用場景存在疑惑。那么,到底是前端用還是后端用呢?本文將從多個角度詳細解答這個問題。…

Node.js_基礎知識(CommonJS模塊化)

CommonJS模塊化規范 加載時機: 服務器端: 模塊的加載是運行時同步加載的,node.js實現了模塊化規范瀏覽器端: 模塊需要提前編譯打包處理,需使用Browserify編譯打包,推薦使用ESM 暴露模塊:module.exports、exports導入模…

“а”搭配使用更地道,柯橋外貿俄語培訓

1、а именно 就是說,就是,正是 例: в то время, а именно год назад. 那時, 也就是一年前。 не кто иной, а именно г-н Ван. 不是別人,就是王先生 2、а наоборот …