前言
本文的文字及圖片來源于網路,僅供學習、交流使用,不具有任何商業用途,著作權歸原作者所有,如有問題請及時聯系我們以作處理,
如今各大網站的反爬機制已經可以說是到了喪心病狂的程度,比如大眾點評的字符加密、微博的登錄驗證等,相比較而言,新聞網站的反爬機制就要稍微弱一點,因此今天以新浪新聞為例,分析如何通過Python爬蟲按關鍵詞抓取相關的新聞,
首先,如果從新聞直接進行搜索,你會發現其內容最多顯示20頁,因此我們要從新浪的首頁進行搜索,這樣才沒有頁數的限制,

網頁結構分析
<div class="pagebox" id="_function_code_page"> <b><span class="pagebox_cur_page">1</span></b> <a href=https://www.cnblogs.com/hhh188764/p/"javascript:;" onclick="getNewsData('https://interface.sina.cn/homepage/search.d.json?t=&q=%E6%97%85%E6%B8%B8&pf=0&ps=0&page=2')" title="第2頁">2</a> <a href=https://www.cnblogs.com/hhh188764/p/"javascript:;" onclick="getNewsData('https://interface.sina.cn/homepage/search.d.json?t=&q=%E6%97%85%E6%B8%B8&pf=0&ps=0&page=3')" title="第3頁">3</a> <a href=https://www.cnblogs.com/hhh188764/p/"javascript:;" onclick="getNewsData('https://interface.sina.cn/homepage/search.d.json?t=&q=%E6%97%85%E6%B8%B8&pf=0&ps=0&page=4')" title="第4頁">4</a> <a href=https://www.cnblogs.com/hhh188764/p/"javascript:;" onclick="getNewsData('https://interface.sina.cn/homepage/search.d.json?t=&q=%E6%97%85%E6%B8%B8&pf=0&ps=0&page=5')" title="第5頁">5</a> <a href=https://www.cnblogs.com/hhh188764/p/"javascript:;" onclick="getNewsData('https://interface.sina.cn/homepage/search.d.json?t=&q=%E6%97%85%E6%B8%B8&pf=0&ps=0&page=6')" title="第6頁">6</a> <a href=https://www.cnblogs.com/hhh188764/p/"javascript:;" onclick="getNewsData('https://interface.sina.cn/homepage/search.d.json?t=&q=%E6%97%85%E6%B8%B8&pf=0&ps=0&page=7')" title="第7頁">7</a> <a href=https://www.cnblogs.com/hhh188764/p/"javascript:;" onclick="getNewsData('https://interface.sina.cn/homepage/search.d.json?t=&q=%E6%97%85%E6%B8%B8&pf=0&ps=0&page=8')" title="第8頁">8</a> <a href=https://www.cnblogs.com/hhh188764/p/"javascript:;" onclick="getNewsData('https://interface.sina.cn/homepage/search.d.json?t=&q=%E6%97%85%E6%B8%B8&pf=0&ps=0&page=9')" title="第9頁">9</a> <a href=https://www.cnblogs.com/hhh188764/p/"javascript:;" onclick="getNewsData('https://interface.sina.cn/homepage/search.d.json?t=&q=%E6%97%85%E6%B8%B8&pf=0&ps=0&page=10')" title="第10頁">10</a> <a href=https://www.cnblogs.com/hhh188764/p/"javascript:;" onclick="getNewsData('https://interface.sina.cn/homepage/search.d.json?t=&q=%E6%97%85%E6%B8%B8&pf=0&ps=0&page=2');" title="下一頁">下一頁</a> </div>
進入新浪網并進行關鍵字搜索之后,發現無論如何翻頁網址都不會變,但是網頁的內容卻更新了,經驗告訴我這是通過ajax完成的,因此我把新浪的網頁代碼拿下來看了看,
顯而易見,每一次翻頁都是通過點擊a標簽向一個地址發送請求,如果你直接將這個地址放入瀏覽器的地址欄并回車:
那么恭喜你,收到錯誤了
認真看一下html的onclick,發現它是呼叫了一個叫getNewsData的函式,因此在相關的js檔案中查找一下這個函式,可以看出它是在每次ajax請求之前構造了請求的url,并且使用get請求,回傳的資料格式為jsonp(跨域),
因此我們只要模仿它的請求格式就可以獲取資料了,
var loopnum = 0; function getNewsData(url){ var oldurl = url; if(!key){ $("#result").html("<span>無搜索熱詞</span>"); return false; } if(!url){ url = 'https://interface.sina.cn/homepage/search.d.json?q='+encodeURIComponent(key); } var stime = getStartDay(); var etime = getEndDay(); url +='&stime='+stime+'&etime='+etime+'&sort=rel&highlight=1&num=10&ie=utf-8'; //'&from=sina_index_hot_words&sort=time&highlight=1&num=10&ie=utf-8'; $.ajax({ type: 'GET', dataType: 'jsonp', cache : false, url:url, success: //回呼函式太長了就不寫了 })
發送請求
import requests headers = { "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:74.0) Gecko/20100101 Firefox/74.0", } params = { "t":"", "q":"旅游", "pf":"0", "ps":"0", "page":"1", "stime":"2019-03-30", "etime":"2020-03-31", "sort":"rel", "highlight":"1", "num":"10", "ie":"utf-8" } response = requests.get("https://interface.sina.cn/homepage/search.d.json?", params=params, headers=headers) print(response)
這次使用的是requests庫,構造相同的url,并發送請求,結果收到的結果是冷冰冰的403Forbidden:
因此重新回到網站看看到底哪里出現了問題
從開發者工具中找到回傳的json檔案,并查看請求頭,發現它的請求頭帶有cookie,因此在構造headers時我們直接復制它的請求頭即可,再次運行,response200!剩下的就簡單了,只需要將回傳的資料決議后寫入Excel,
完整代碼
import requests import json import xlwt def getData(page, news): headers = { "Host": "interface.sina.cn", "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:74.0) Gecko/20100101 Firefox/74.0", "Accept": "*/*", "Accept-Language": "zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2", "Accept-Encoding": "gzip, deflate, br", "Connection": "keep-alive", "Referer": r"http://www.sina.com.cn/mid/search.shtml?range=all&c=news&q=%E6%97%85%E6%B8%B8&from=home&ie=utf-8", "Cookie": "ustat=__172.16.93.31_1580710312_0.68442000; genTime=1580710312; vt=99; Apache=9855012519393.69.1585552043971; SINAGLOBAL=9855012519393.69.1585552043971; ULV=1585552043972:1:1:1:9855012519393.69.1585552043971:; historyRecord={'href':'https://news.sina.cn/','refer':'https://sina.cn/'}; SMART=0; dfz_loc=gd-default", "TE": "Trailers" } params = { "t":"", "q":"旅游", "pf":"0", "ps":"0", "page":page, "stime":"2019-03-30", "etime":"2020-03-31", "sort":"rel", "highlight":"1", "num":"10", "ie":"utf-8" } response = requests.get("https://interface.sina.cn/homepage/search.d.json?", params=params, headers=headers) dic = json.loads(response.text) news += dic["result"]["list"] return news def writeData(news): workbook = xlwt.Workbook(encoding = 'utf-8') worksheet = workbook.add_sheet('MySheet') worksheet.write(0, 0, "標題") worksheet.write(0, 1, "時間") worksheet.write(0, 2, "媒體") worksheet.write(0, 3, "網址") for i in range(len(news)): print(news[i]) worksheet.write(i+1, 0, news[i]["origin_title"]) worksheet.write(i+1, 1, news[i]["datetime"]) worksheet.write(i+1, 2, news[i]["media"]) worksheet.write(i+1, 3, news[i]["url"]) workbook.save('data.xls') def main(): news = [] for i in range(1,501): news = getData(i, news) writeData(news) if __name__ == '__main__': main()
最終結果
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/109003.html
標籤:Python
上一篇:疫情后來場說走就走的旅行,Python制作一份可視化的旅行攻略
下一篇:初探numpy——陣列的創建

