Python 爬蟲實戰:爬取解放日報新聞文章

2021-12-28 機靈鶴

上一篇《Python 爬蟲實戰: 爬取人民日報新聞文章》發布之後,確實幫到了不少朋友。

這篇文章我們爬取《解放日報》新聞文章,同樣是面向爬蟲新手的零基礎教程。

一、分析網站

首先應該 明確需求,就是要明確我們需要什麼樣的數據,以什麼樣的形式來保存等等。不過我們這個爬蟲需求跟《人民日報》爬蟲一致,這部分暫且略過,我們直接來分析網站。

解放日報的訪問地址如下:

https://www.shobserver.com/staticsg/res/html/journal/index.html?date=2021-12-22&page=01

其主界面跟 人民日報 網站非常相似,都是 版面列表 -- 文章列表 -- 文章詳情 的這種結構。

不過簡單分析後發現,這個網站的新聞數據是通過 Ajax 動態加載出來的(人民日報的數據是靜態加載的),也就是說,我們無法直接解析 html 源碼獲得數據。

1.1 數據動態加載是怎麼回事兒很多剛接觸爬蟲的同學,習慣上來 F12 打開開發者工具,然後就咔咔定位數據找標籤。如果是像人民日報那樣的靜態網頁還好,你分析時看到的標籤是什麼樣子,用代碼爬的時候基本上也是那個樣子。但是遇到解放日報這種 動態加載 的網站,就直接懵逼了,明明我標籤位置,名字,class 和 id 什麼的都沒寫錯,為什麼爬取的時候就總是報錯說找不到標籤呢?

答案就是,你找的那個標籤是動態生成的,原始網頁源碼裡根本沒有,當然找不到了。

大家看下面,這是解放日報的版面導航列表。

一般大家爬取的時候,會先找到這個 <div> 標籤,然後在這個標籤下找到所有的 <dd> 標籤,然後再找 <a> 標籤,然後就找到了想要的數據。

然鵝,當我們打開查看網頁源碼的時候(chrome 瀏覽器為例,滑鼠右鍵,查看網頁原始碼),發現原始碼裡並沒有我們需要的數據,而是一個類似於模板的東西。數據是通過後續動態的加載進來的。

當我們用爬蟲去爬的時候,獲取到的也是這樣的原始碼,當然取不到數據啦。

Tips1: 分析網頁的時候,可以先查看一下網頁原始碼,看看自己需要的數據是否在裡面,如果有,則可以繼續接著分析,如果沒有,說明數據是動態加載進來的,要換個思路。

1.2 數據是怎麼獲取到的

既然網頁原始碼中找不到數據,那麼我們去哪兒獲得數據呢?

這就涉及到一個詞,叫 「抓包」 ,可能聽上去很高深很難的樣子,其實很簡單的。我們知道數據肯定是通過發起 網絡請求 獲得的,就是網頁向伺服器發送一條請求,然後伺服器把需要的數據回復回來,我們把網頁向伺服器發送的請求,和瀏覽器返回的數據,使用一些工具和手段截獲下來進行分析,這個過程就是 「抓包」。

可能大家聽著還是有點迷糊,下面我來具體演示一下。

首先打開開發者工具,切換到 Network,然後刷新網頁(這裡可以抓到網頁加載過程中,向伺服器發起的各種類型的請求)。

然後上圖紅框中圈出來的,就是我們抓取到的一條一條的請求包,有 js 腳本的,有 css 文件的,還有圖片的等等各種類型的。我們要在這麼多的 「請求包」 裡找到包含我們需要的數據的包。

把列表裡的這些請求從上到下一條一條的點開(在 Preview 裡可以預覽請求返回的數據),查看哪條請求是我們想要找的。

如圖的請求點開以後, Response 裡的內容正好就是版面導航欄裡的內容,我們成功找到了正確的請求。

至此,我們抓包成功!這條請求也就是我們抓到的 "" 。

1.3 抓到的包怎麼用?

含有數據的請求包我們是抓到了,但是我們具體要怎麼用呢?怎麼把它用到爬蟲程序裡,通過它來爬數據呢?

還是那條請求,我們切換到 Headers 頁籤,可以查看到關於這條請求的一些基本信息。

主要關注幾個部分 Request URL(請求連結),Request Method(請求方法),Query String Parameters(請求參數),(當然請求頭的那些東西,User-Agent ,Cookie 什麼的,按照實際情況該怎麼加就怎麼加)。

我們的目的就是,通過 python 代碼模擬瀏覽器發出這條請求,直接獲取伺服器返回的數據(返回的數據就是前面預覽裡的那些)。

import requests
url = "https://www.shobserver.com/staticsg/data/journal/2021-12-22/navi.json?ver=1640171036910"r = requests.get(url)print(r.text)

我們簡單寫幾行代碼模擬一下這個過程(url 就是上圖中 Request URL 的內容,requests.get() 是因為 Request Method 是 GET )。

運行代碼,可以成功獲得數據。

1.4 怎麼爬其他日期的數據

運行上面的代碼,我們可以獲得到 2021 年 12 月 22日的新聞數據,那我們如果想爬其他日期的新聞數據該怎麼辦呢?

這裡我們觀察一下請求的 url

https://www.shobserver.com/staticsg/data/journal/2021-12-22/navi.json?ver=1640171036910

其中有一段 2021-012-22 的字樣,我們猜測,這個可能就是用來控制獲取數據的日期的,改成別的日期 比如 2021-04-20 再試一下。

https://www.shobserver.com/staticsg/data/journal/2021-04-20/navi.json?ver=1640171036910

發現同樣可以成功。

這樣我們就知道,可以通過修改 url 裡的日期字符串,來爬取指定日期的數據。

1.5 解析數據

該請求返回的數據,是 json 格式的字符串,我們需要用 json 庫來進行解析。

有同學可能想問了,那麼一大串亂碼似的文字,你怎麼知道它是 json 格式的呢?簡單來講,看兩個特點,一個是大括號 {} 包起來的,另一個是鍵值對格式,就是 xxx : xxx 這種形式的。實在不知道怎麼判斷的話,就去前面講抓包的部分,看預覽的地方,如果有小箭頭能夠摺疊展開的,就是 json 格式。

我們可以看到 pages 裡有版面的列表,每個版面的 articleList 裡有文章列表,包含了我們需要的版面和文章列表信息。具體解析的 Python 代碼這裡就不講了,文末會貼源碼。

1.6 怎麼爬文章詳細內容

首先點開一個文章的正文頁,用前面同樣的分析方法過一遍,很容易知道,正文內容也是動態加載進來的,而且正文的數據是通過下面這條請求來獲得到的。

我們簡單寫段代碼來驗證一下

import requests
url = "https://www.shobserver.com/staticsg/data/journal/2021-12-22/01/article/326701.json?ver=1640174508325"r = requests.get(url)print(r.text)

運行結果

經過對這條請求的 url 的分析,我們可以知道,/2021-12-22 是日期,/01 是指版面的編號,/326701 是文章的 id。

https://www.shobserver.com/staticsg/data/journal/2021-12-22/01/article/326701.json?ver=1640174508325

至此,我們完成了對網站的分析,講解了如何判斷網站數據是動態加載還是靜態加載,如果是動態加載的話如何抓包,抓包以後如何使用等等,並抓到了 新聞版面列表文章列表文章正文內容 的請求接口。如果有哪裡沒有講清楚,或者對以上內容有不太明白的地方,可以留言問我。

下面進行寫代碼,正式爬取。

二、編碼環節

下面是爬蟲源碼,供大家學習交流使用,請勿用於非法用途。

import requestsimport bs4import osimport datetimeimport timeimport json def fetchUrl(url):    '''    功能:訪問 url 的網頁,獲取網頁內容並返回    參數:目標網頁的 url    返回:目標網頁的 html 內容    '''    headers = {        'accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8',        'user-agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36',    }    r = requests.get(url, headers=headers)    r.raise_for_status()    r.encoding = r.apparent_encoding    return r.text
def saveFile(content, path, filename): ''' 功能:將文章內容 content 保存到本地文件中 參數:要保存的內容,路徑,文件名 ''' if not os.path.exists(path): os.makedirs(path) with open(path + filename, 'w', encoding='utf-8') as f: f.write(content)
def download_rmrb(year, month, day, destdir): ''' 功能:網站 某年 某月 某日 的新聞內容,並保存在 指定目錄下 參數:年,月,日,文件保存的根目錄 ''' url = 'https://www.shobserver.com/staticsg/data/journal/' + year + '-' + month + '-' + day + '/navi.json' html = fetchUrl(url) jsonObj = json.loads(html)
for page in jsonObj["pages"]: pageName = page["pname"] pageNo = page["pnumber"] print(pageNo, pageName) for article in page["articleList"]: title = article["title"] subtitle = article["subtitle"] pid = article["id"] url = "https://www.shobserver.com/staticsg/data/journal/" + year + '-' + month + '-' + day + "/" + str(pageNo) + "/article/" + str(pid) + ".json" print(pid, title, subtitle)
html = fetchUrl(url) cont = json.loads(html)["article"]["content"] bsobj = bs4.BeautifulSoup(cont, 'html.parser') content = title + subtitle + bsobj.text path = destdir + '/' + year + month + day + '/' + str(pageNo) + " " + pageName + "/" fileName = year + month + day + '-' + pageNo + '-' + str(pid) + '.txt' saveFile(content, path, fileName) def gen_dates(b_date, days): day = datetime.timedelta(days = 1) for i in range(days): yield b_date + day * i def get_date_list(beginDate, endDate): """ 獲取日期列表 :param start: 開始日期 :param end: 結束日期 :return: 開始日期和結束日期之間的日期列表 """ start = datetime.datetime.strptime(beginDate, "%Y%m%d") end = datetime.datetime.strptime(endDate, "%Y%m%d") data = [] for d in gen_dates(start, (end-start).days): data.append(d) return data
if __name__ == '__main__': ''' 主函數:程序入口,提供了兩種爬取方式,爬取指定日期的新聞 or 爬取時間段內的新聞    '''     beginDate = input('請輸入開始日期:') endDate = input('請輸入結束日期:') data = get_date_list(beginDate, endDate) for d in data: year = str(d.year) month = str(d.month) if d.month >=10 else '0' + str(d.month) day = str(d.day) if d.day >=10 else '0' + str(d.day) download_rmrb(year, month, day, f'Data/{year}') print("爬取完成:" + year + month + day)

以上是爬取解放日報新聞文章的爬蟲源碼,如果爬取量較大的話,建議加上 time.sleep() 函數,降低被反爬的機率。

三、運行效果

運行程序,輸入 起始日期 終止日期 後,爬蟲會自動下載該時間段內的新聞文章,並保存在 Data 目錄下相應的文件夾中。

如果文章中有哪裡沒有講明白,或者講解有誤的地方,歡迎在評論區批評指正,或者掃描下面的二維碼,加我微信,大家一起學習交流,共同進步。

相關焦點

  • 【Python爬蟲進階】不需要了解網頁架構,也能從網站上爬取新聞文章
    前幾天,公司給我安排了一個新項目,要求在網上爬取新聞文章。為了用最簡單、最快的方法來完成此任務,特意做了一些準備。
  • Python爬蟲實戰(2):爬取京東商品列表
    在上一篇《Python爬蟲實戰:爬取Drupal論壇帖子列表》,爬取了一個用Drupal做的論壇,是靜態頁面,抓取比較容易,即使直接解析
  • 小白學 Python 爬蟲(25):爬取股票信息
    (二)小白學 Python 爬蟲(13):urllib 基礎使用(三)小白學 Python 爬蟲(14):urllib 基礎使用(四)小白學 Python 爬蟲(15):urllib 基礎使用(五)小白學 Python 爬蟲(16):urllib 實戰之爬取妹子圖小白學 Python 爬蟲(17):Requests 基礎使用
  • python爬蟲實戰:爬取全站小說排行榜
    新筆趣閣是廣大書友最值得收藏的網絡小說閱讀網,網站收錄了當前.我就不打廣告了(其他滿足下文條件的網站也行,之前已經有做過簡單爬取章節的先例了,但效果不太理想,有很多不需要的成分被留下了,來連結:http://python.jobbole.com
  • 用python爬蟲爬取圖片實戰
    爬取糗事百科用戶的頭像圖片#爬取圖片的關鍵:構建頭像的正則表達式# pattern
  • Python網絡爬蟲應用實戰
    從小到伺服器運維的腳本,到大型軟體開發,使用python都能夠很靈活的快速實現。python不但可以快速實現大型的web應用程式,在網絡層的開發,以及工程計算、數學計算上都有方便的開發手段。Map&Reduce思想在python裡面也有著非常方便的實現。甚至在一些嵌入式設備上,你也可以實現自己的python應用。
  • Pyspider框架 —— Python爬蟲實戰之爬取 V2EX 網站帖子
  • 手把手教你用python 爬取京東評論
    本次python實戰,主要目標是利用 Python爬取京東商品評論數,如上圖所示:爬取「Python之父」推薦的小藍書,這些信息主要包括用戶名、
  • 推薦18個Python爬蟲實戰案例
    目錄爬蟲小工具爬蟲實戰筆趣看小說下載VIP視頻下載百度文庫文章下載_rev1百度文庫文章下載_rev2《帥啊》網帥哥圖片下載構建代理IP池《火影忍者》漫畫下載財務報表下載小助手一小時入門網絡爬蟲抖音App視頻下載_rev1
  • [Python爬蟲]使用Python爬取靜態網頁-鬥魚直播
    作者:宅必備一個會寫Python的Oracle DBA個人公眾號:宅必備作者其他文章:
  • 18個Python爬蟲實戰案例(已開源)
    點擊上方「Python技術之巔」,馬上關注,每天下午17:40準時推送目錄爬蟲小工具爬蟲實戰筆趣看小說下載VIP視頻下載百度文庫文章下載_rev1百度文庫文章下載_rev2《帥啊》網帥哥圖片下載構建代理IP池
  • 乾貨 | 18個Python爬蟲實戰案例(已開源)
    目錄爬蟲小工具爬蟲實戰筆趣看小說下載VIP視頻下載百度文庫文章下載_rev1
  • 大數據之如何利用爬蟲爬取數據做分析
    爬蟲想必很多人都聽過,這裡簡單介紹下爬蟲,爬蟲是一段可以在網頁上自動抓取信息的程序,可以幫助我們獲取一些有用的信息。
  • Python爬蟲學習教程 bilibili網站視頻爬取!【附源碼】
    Python爬蟲學習教程,萬物皆可爬!每個技術大牛都是從基礎慢慢的提升上去的,基礎知識越深以後的發展越牛!
  • Python爬蟲 | Selenium爬取噹噹暢銷圖書排行
    點擊上方「Python爬蟲與數據挖掘」,進行關注回復「書籍」即可獲贈Python從入門到進階共10本電子書專欄作者:霖hero,在職爬蟲工程師,熟悉JS逆向與分布式爬蟲。喜歡鑽研,熱愛學習,樂於分享。上篇文章我們爬取了今日頭條街拍美圖,心情相當愉悅,今天這篇文章我們使用Selenium來爬取當當網的暢銷圖書排行。正所謂書中自有黃金屋,書中自有顏如玉,我們通過讀書學習來提高自身的才華,自然能有榮華富貴,也自然少不了漂亮小姐姐。在爬取數據前,我們需要安裝Selenium庫以及Chrome瀏覽器,並配置好ChromeDriver。
  • Python爬蟲 - scrapy - 爬取豆瓣電影TOP250
    前言新接觸爬蟲,經過一段時間的實踐,寫了幾個簡單爬蟲,爬取豆瓣電影的爬蟲例子網上有很多,但都很簡單,大部分只介紹了請求頁面和解析部分,對於新手而言
  • 利用python爬蟲爬取網站音樂遇到的坑
    當然,方法還是有很多種的,最後我還是選擇了一種最簡單,最方便的一種方法: python爬蟲。下面,我就跟大家分享一下我在用python爬蟲時遇到的坑。下面,我以爬取某易雲音樂為例,介紹一下我時如何學習python爬蟲的:思路:音樂從哪裡來?---網站的伺服器裡怎麼從網址裡得到音樂?
  • 爬蟲神器 Pyppeteer 介紹及爬取某商城實戰
    介紹 Pyppeteer 之前先說一下 Puppeteer,Puppeteer 是 Google 基於 Node.js 開發的一個工具,主要是用來操縱 Chrome 瀏覽器的 API,通過 Javascript 代碼來操縱 Chrome 瀏覽器的一些操作,用作網絡爬蟲進行數據爬取、Web 程序自動測試等任務。其 API 極其完善,功能非常強大。
  • 利用python爬取 有道詞典
    前言大家好最近python爬蟲有點火啊,啥python爬取馬保國視頻……我也來湊個熱鬧,今天我們來試著做個翻譯軟體……不是不是,說錯了
  • 任意爬取!超全開源Python爬蟲工具箱
    結構清晰:本項目的所有數據源相互獨立,可移植性高,所有爬蟲腳本在項目的 Spiders 文件下。數據源豐富:本項目目前支持多達24+個數據源,持續更新。數據格式統一:爬取的所有數據都將存儲為json格式,方便後期數據分析。