Python爬蟲:新浪新聞詳情頁的數據抓取(函數版)
上一篇文章《Python爬蟲:抓取新浪新聞數據》詳細解說了如何抓取新浪新聞詳情頁的相關數據,但代碼的構建不利於後續擴展,每次抓取新的詳情頁時都需要重新寫一遍,因此,我們需要將其整理成函數,方便直接調用。
詳情頁抓取的6個數據:新聞標題、評論數、時間、來源、正文、責任編輯。
首先,我們先將評論數整理成函數形式表示:
1 import requests 2 import json 3 import re 4 5 comments_url = ‘http://comment5.news.sina.com.cn/page/info?version=1&format=js&channel=gn&newsid=comos-{}&group=&compress=0&ie=utf-8&oe=utf-8&page=1&page_size=20‘ 6 7 def getCommentsCount(newsURL): 8 ID = re.search(‘doc-i(.+).shtml‘, newsURL) 9 newsID = ID.group(1) 10 commentsURL = requests.get(comments_url.format(newsID)) 11 commentsTotal = json.loads(commentsURL.text.strip(‘var data=‘)) 12 return commentsTotal[‘result‘][‘count‘][‘total‘] 13 14 news = ‘http://news.sina.com.cn/c/nd/2017-05-14/doc-ifyfeius7904403.shtml‘ 15 print(getCommentsCount(news))
第5行comments_url,在上一篇中,我們知道評論鏈接中有新聞ID,不同新聞的評論數通過該新聞ID的變換而變換,因此我們將其格式化,新聞ID處用大括號{}來替代;
定義獲取評論數的函數getCommentsCount,通過正則來查找匹配的新聞ID,然後將獲取的新聞鏈接存儲進變量commentsURL中,通過解碼JS來得到最終的評論數commentsTotal;
然後,我們只需輸入新的新聞鏈接,便可直接調用函數getCommentsCount來獲取評論數。
最後,我們將需要抓取的6個數據均整理到一個函數getNewsDetail中。如下:
1 from bs4 import BeautifulSoup 2 import requests 3 from datetime import datetime 4 import json 5 import re 6 7 comments_url = ‘http://comment5.news.sina.com.cn/page/info?version=1&format=js&channel=gn&newsid=comos-{}&group=&compress=0&ie=utf-8&oe=utf-8&page=1&page_size=20‘ 8 9 def getCommentsCount(newsURL): 10 ID = re.search(‘doc-i(.+).shtml‘, newsURL) 11 newsID = ID.group(1) 12 commentsURL = requests.get(comments_url.format(newsID)) 13 commentsTotal = json.loads(commentsURL.text.strip(‘var data=‘)) 14 return commentsTotal[‘result‘][‘count‘][‘total‘] 15 16 # news = ‘http://news.sina.com.cn/c/nd/2017-05-14/doc-ifyfeius7904403.shtml‘ 17 # print(getCommentsCount(news)) 18 19 def getNewsDetail(news_url): 20 result = {} 21 web_data = requests.get(news_url) 22 web_data.encoding = ‘utf-8‘ 23 soup = BeautifulSoup(web_data.text,‘lxml‘) 24 result[‘title‘] = soup.select(‘#artibodyTitle‘)[0].text 25 result[‘comments‘] = getCommentsCount(news_url) 26 time = soup.select(‘.time-source‘)[0].contents[0].strip() 27 result[‘dt‘] = datetime.strptime(time,‘%Y年%m月%d日%H:%M‘) 28 result[‘source‘] = soup.select(‘.time-source span span a‘)[0].text 29 result[‘article‘] = ‘ ‘.join([p.text.strip() for p in soup.select(‘#artibody p‘)[:-1]]) 30 result[‘editor‘] = soup.select(‘.article-editor‘)[0].text.lstrip(‘責任編輯:‘) 31 return result 32 33 print(getNewsDetail(‘http://news.sina.com.cn/c/nd/2017-05-14/doc-ifyfeius7904403.shtml‘))
在函數getNewsDetail中,獲取需要抓取的6個數據,放在result中:
- result[‘title‘]是獲取新聞標題;
- resul[‘comments‘]是獲取評論數,可以直接調用我們開頭定義的評論數函數getCommentsCount;
- result[‘dt‘]是獲取時間; result[‘source‘]是獲取來源;
- result[‘article‘]是獲取正文;
- result[‘editor‘]是獲取責任編輯。
而後輸入自己想要獲取數據的新聞鏈接,調用該函數即可。
部分運行結果:
{‘title‘: ‘浙大附中開課教詠春 “教頭”系葉問第三代弟子‘, ‘comments‘: 618, ‘dt‘: datetime.datetime(2017, 5, 14, 7, 22), ‘source‘: ‘中國新聞網‘, ‘article‘: ‘原標題:浙大附中開課教詠春 “教頭”系葉問......來源:錢江晚報‘, ‘editor‘: ‘張迪 ‘}
Mac,Python版本:3.6,PyCharm版本:2016.2
----- End -----
作者:杜王丹,微信公眾號:杜王丹,互聯網產品經理。
Python爬蟲:新浪新聞詳情頁的數據抓取(函數版)