scrapy爬蟲抓取百度網頁(結果列表頁和原文頁正文提取)

本項目能夠針對給定的搜索關鍵詞列表,抓取百度網頁搜索的前N頁搜索結果。

主要貢獻點:通過綜合利用正文提取工具(jparser+url2io),提高了搜索結果原文的正文提取成功率和準確率。

本文完整代碼詳見:https://github.com/Neo-Luo/scrapy_baidu

需求

提供搜索關鍵詞列表,針對每個關鍵詞,返回搜索結果頁前N頁的搜索結果,保存爲csv文件。

保存字段:
(1)搜索結果列表頁:標題,摘要,發佈時間,原文鏈接。
(2)每一條搜索結果對應的正文。

爬蟲設計

主要python包:requests+BeautifulSoup+jparser+url2io。
其中jparser、url2io都用於網頁文本正文提取,url2io準確率高,但不穩定,解析錯誤時則調用jparser。通過兩者結合使用來提高正文提取的效果。

jparser

url2io

主要代碼

# -*- coding:utf-8 -*-
import os
import requests
import time
import csv
import re
from bs4 import BeautifulSoup
import urllib2
from jparser import PageModel
import url2io

token = 'xxxx' #請到url2io官網註冊獲取token
api = url2io.API(token)

headers = {
    'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
    'Accept-Language': 'en-us;q=0.5,en;q=0.3',
    'Cache-Control': 'max-age=0',
    'Connection': 'keep-alive',
    'User-Agent': 'Mozilla/5.0 (X11; Ubuntu; Linux x86_64; rv:22.0) Gecko/20100101 Firefox/22.0'
}

SAVE_DIR = 'scrapy_data' #抓取數據存儲路徑
if not (os.path.isdir(SAVE_DIR)):
    os.makedirs(SAVE_DIR)

# 主函數    
def main():
    reader = csv.reader(open( 'query_text.csv', 'rb'))
    index = 0
    for line in reader:
        record_id = 1
        query_all = line[0]
        csvfile = open( SAVE_DIR +'/scrapy_result_%i.csv' % (index), 'wb')
        writer = csv.writer(csvfile)
        data = ['record_id','query','title','abstract','link','content']
        writer.writerows([data])
 
        query_array = re.split(u"[,;。!?]", query_all.decode('utf-8'))
        if(len(query_array)):
            for query in query_array:
                    PAGE_NUM = 2 #抓取頁數設置
                
                for k in range(0, PAGE_NUM):
                    try:
                        #待抓取的網頁地址
                        url = 'http://www.baidu.com/s?wd=%s&pn=%i' % (query,k*10)
                        content = requests.get(url,headers=headers)
                        #使用BeautifulSoup解析html
                        soup = BeautifulSoup(content.text,'html.parser')
                        title = []
                        abstract = []
                        link = []
                        content = []
                        allNews = soup.find_all('div', { 'class', 'result c-container '})
                        for hotNews in allNews:
                            h3 = hotNews.find(name = "h3", attrs = { "class": re.compile( "t")}).find('a')
                            title.append(h3.text.replace("\"",""))
                            div = hotNews.find(name = "div", attrs = { "class": re.compile( "c-abstract")})
                            abstract.append(div.text.replace("\"",""))
                            a = hotNews.find(name = "a", attrs = { "class": re.compile( "c-showurl")})
                            detail_url = a.get('href')
                            link.append(detail_url)
                            # 正文提取模塊
                            try:
                            	# url2io初步嘗試提取
                                ret = api.article(url=detail_url, fields=['text', 'next'])
                                content.append(ret['text'].replace('\r','').replace('\n',''))
                            except:
                                try:
                                	# 第一次提取失敗,url2io第二次嘗試提取
                                    time.sleep(1)
                                    ret = api.article(url=detail_url, fields=['text'])
                                    content.append(ret['text'].replace('\r','').replace('\n',''))
                                except:
                                    try:
                                    	# 第2次提取失敗的話,改用jparser提取
                                        try:
                                            html = requests.get(detail_url,headers=headers).text.decode('utf-8')
                                        except:
                                            html = requests.get(detail_url,headers=headers).text.decode('gbk')
                                        pm = PageModel(html)
                                        result = pm.extract()
                                        ans = [ x['data'] for x in result['content'] if x['type'] == 'text']
                                        content.append(''.join(ans))
                                    except Exception as e:
                                        print(e)
                                        print(detail_url)
                                        content.append('')
                                        pass

                        #將數據寫入csv
                        data = []                        
                        for i in range( 0, len(title)):
                            try:
                                data.append((record_id,query,title[i],abstract[i],link[i],content[i]))
                                record_id += 1
                            except Exception as err:
                                print(err)
                        writer.writerows(data)
                        print("Page: " + str(k+1) + " finished!")

                    except Exception as err:
                        print(err)
                        pass

            
        csvfile.close()


if __name__ == '__main__':
    main()


抓取結果展示

record_id,query,title,abstract,link,content
1,消息面看貿易戰進入持久戰當下只能說是短暫靴子落地美公佈關稅豁免程序,貿易戰後操作思路_烽火通信(600498)聊吧_贏家聊吧【股吧】,“貿易戰既然已經開始,時間上持久戰的概率較大。而當下也只能說是短暫的靴子落地,隨時還有再起烽火可能,美國公佈了個關稅豁免程序但那只是正常程序,切勿就…”,http://www.baidu.com/link?url=fJ5P3mDdJxPJPBMMaMXI66n0_l72H4Q-ouH3LrM6jwrPW3_Eknpa2LfH_fk3zh_29wqXlDRCR9--xoHr1YMLLa, 週五盤面情緒波動過激主要來源於中美貿易……短線宜做逆風的牆頭草,即再跌不悲觀,反彈則不能盲目樂觀,操作上忌追漲殺跌。把控倉位、跟隨市場熱點小打小鬧爲好。
2,消息面看貿易戰進入持久戰當下只能說是短暫靴子落地美公佈關稅豁免程序,“保持淡定,爲什麼說“貿易戰”並不可怕?”,“2018年3月26日 - 既然靴子還沒有落地,就不必過於驚慌,意向在落實…周邊市場的需求推動下,我認爲長期看是利好消息…美商務部長:懲罰關稅不會引發貿易戰,最終會以談判…”,http://www.baidu.com/link?url=SJ5MEHBKnkWGAdHs_6HCZgjvx1ou6ZVDxEA64Sp_Le5gLoXcyVzn7eL0GDzn4yMi7x5HxOmiMr0jdl_EOtEet_7TGJFxSYnbTIOjdJA81Y_, 霸越英百家號03-2619:31讓我們先來回顧下當下熱議的貿易戰的由來——媒體錯誤描述貿易戰經過3月8日,美國總統特朗普宣佈,以損害國家安全爲由……另外2017年出口對於GDP的貢獻度只有18.5%,即使600億美元產品徵稅導致出口額全部取消,對於中國GDP的影響也只有4%*18.5%=0.74%。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章