爬蟲日記---七日熱點(diǎn)scrapy版

受大牛們的鼓勵,繼2個熬夜的晚上終于做完scrapy版的“七日熱點(diǎn)”。寶寶好累奥洼,做到凌晨,電腦差一點(diǎn)被收走晚胡。 趕緊開始記錄灵奖。

主要參考文章:

Scrapy 0.24 文檔
Scrapy爬取"單頁面"數(shù)據(jù)(一)
Scrapy爬取多層網(wǎng)頁結(jié)構(gòu)數(shù)據(jù)(二)
Scrapy抓取多層網(wǎng)頁結(jié)構(gòu)詳解(三)
爬蟲小分隊二組Scrapy框架收錄專題-20170423(二)

Scrapy 是專門用來爬取網(wǎng)站數(shù)據(jù)的應(yīng)用框架。不能直接用pycharm來創(chuàng)建一個scrapy的project估盘。需要現(xiàn)在shell中寫入scrapy startproject 項目名稱瓷患。然后打開pycharm,就會生成類似于如下多個py文件組成項目遣妥。

項目名稱/
    scrapy.cfg
    tutorial/
        __init__.py
        items.py
        pipelines.py
        settings.py
        spiders/
            __init__.py
            ...

具體每個py文件的功能可以查找相關(guān)資料∩帽啵現(xiàn)在需要做的是在spiders目錄下新建一個你的爬蟲主的py文件。這就是你要寫爬蟲的主要地方箫踩。

代碼如下組成

1爱态、items.py

存儲爬取數(shù)據(jù)。 其類型類似于詞典境钟。用于聲明可用字段的簡單語法锦担。

from scrapy import Item,Field

class SevendayItem(Item):
    # define the fields for your item here like:
    # name = scrapy.Field()
    user=Field() #作者
    title=Field() #標(biāo)題
    read_qty=Field() #閱讀量
    commend_qty=Field() #評論數(shù)量
    admire_qty=Field() #喜歡數(shù)量
    reward=Field() #打賞
    topic=Field() #被收入專題

2、settings.py

設(shè)置CSV文件存儲位置和本機(jī)的user_agent

USER_AGENT='Mozilla/5.0 (Macintosh; Intel Mac OS X 10_12_4) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/57.0.2987.133 Safari/537.36'
FEED_URI=u'sevenday.csv'
FEED_FORMAT='CSV'

3慨削、main.py

啟動爬蟲

#-*- coding:utf-8 -*-
from scrapy import cmdline
cmdline.execute("scrapy crawl sevenday1".split())

4洞渔、sevenday.py

#-*- coding:utf-8 -*-
import sys
sys.path.append('..')
from scrapy.spiders import CrawlSpider
from scrapy.http import Request
from items import SevendayItem
from scrapy.selector import Selector
import sys
import re
import json

reload(sys)
sys.setdefaultencoding('utf-8')

class sevenday(CrawlSpider):
    name='sevenday1'
    start_urls=['http://www.reibang.com/trending/weekly?utm_medium=index-banner-s&utm_source=desktop&page=1']

    def parse(self, response):
        selector=Selector(response)
        datas=selector.xpath('//ul[@class="note-list"]/li')
        for data in datas:
            base_url = data.xpath('div/a/@href')
            if base_url:
                detail_url='http://www.reibang.com'+data.xpath('div/a/@href').extract()[0]
                print 'ddd',detail_url
                yield Request(detail_url,callback=self.parse_item)
        urls = ['http://www.reibang.com/trending/weekly?utm_medium=index-banner-s&utm_source=desktop&page={}'.format(i) for i in range(2, 9)]
        for newurl in urls:
            yield Request(newurl, callback=self.parse)

    def parse_item(self, response):
        #items=[]
        item=SevendayItem()
        selector=Selector(response)
        user=selector.xpath('//span[@class="name"]/a/text()').extract()[0]
        title=selector.xpath('//div[@class="article"]/h1[@class="title"]/text()').extract()[0]
        read_qty=re.findall('"views_count":(.*?),', response.text, re.S)[0]
        comment_qty = re.findall('"comments_count":(.*?),', response.text, re.S)[0]
        admire_qty=re.findall('"likes_count":(.*?),', response.text, re.S)[0]
        id = re.findall('"id":(.*?),', response.text, re.S)[0]
        reward_url = ['http://www.reibang.com/notes/{}/rewards.json'.format(str(id))]
        print reward_url[0]
        item['user']=user
        item['title']=title
        item['read_qty']=read_qty
        item['commend_qty']=comment_qty
        item['admire_qty']=admire_qty
        #items.append(item)
        #yield Request(reward_url[0],meta={'id':id,'user':user,'title':title,'read_qty':read_qty,'comment_qty':comment_qty,'admire_qty':admire_qty},callback=self.parse_info)
        yield Request(reward_url[0],meta={'id':id,'item':item},callback=self.parse_info)

    def parse_info(self,response):
        selector=Selector(response)
        item1=response.meta['item']
        item=SevendayItem()
        item['user']=item1['user']
        item['title'] = item1['title']
        item['read_qty'] = item1['read_qty']
        item['commend_qty'] = item1['commend_qty']
        item['admire_qty'] = item1['admire_qty']
        reward_detail = json.loads(response.text)
        reward_qty = reward_detail['rewards_count']
        print 'ssss',reward_qty
        item['reward']=reward_qty
        id=response.meta['id']
        html_collection_url = 'http://www.reibang.com/notes/%s/included_collections.jason' % id
        yield Request(html_collection_url,meta={'item':item},callback=self.parse_collection)

    def parse_collection(self,response):
        item1=response.meta['item']
        item=SevendayItem()
        datas=[]
        collection_detail=json.loads(response.text)
        for one in collection_detail['collections']:
            datas.append(one['title'])
        data = ','.join(datas)
        item['topic']=data
        item['user'] = item1['user']
        item['title'] = item1['title']
        item['read_qty'] = item1['read_qty']
        item['commend_qty'] = item1['commend_qty']
        item['admire_qty'] = item1['admire_qty']
        item['reward']=item1['reward']
        yield item

重點(diǎn)分析sevenday.py部分知識點(diǎn):

class sevenday(CrawlSpider):
    name='sevenday1'  #爬蟲名字,
    start_urls=['http://www.reibang.com/trending/weekly?utm_medium=index-banner-s&utm_source=desktop&page=1']
    def parse(self, response):
         urls = ['http://www.reibang.com/trending/weekly?utm_medium=index-banner-s&utm_source=desktop&page={}'.format(i) for i in range(2, 9)]
         for newurl in urls:
            yield Request(newurl, callback=self.parse)

name='sevenday1'是爬蟲名字缚态,要和上邊的類“sevenday"取不一樣的名稱磁椒,在main.py 會啟動這個爬蟲名稱來運(yùn)行爬蟲
start_urls是啟動爬蟲最初進(jìn)入的url
def parse(self, response):是一個用來解析這個start_urls的頁面的函數(shù)。
其中response就是請求返回的響應(yīng)的參數(shù)猿规。
它的作用就像相當(dāng)于單線程爬蟲中的:

url='http://*****'
html=requests.get(url).content

可以用parse函數(shù)來解析start_urls的HTML源碼來提取數(shù)據(jù)衷快。例如:

 def parse(self, response):
    selector=Selector(response)
    datas=selector.xpath('//ul[@class="note-list"]/li')

類Selector是一個Scrapy的選擇器。通過特定的XPath表達(dá)式來“選擇” HTML文件中的某個部分姨俩。上邊的例子通過xpath選取包含class="note-list"的標(biāo)簽ul下的li標(biāo)簽蘸拔。通過網(wǎng)頁分析,datas是一個列表环葵。不確定的可以在這里打印datas看一下调窍。
接上邊,urls是一個新創(chuàng)建的url列表张遭,通過for循環(huán)邓萨,游遍所有urls的地址.
yield Request(newurl, callback=self.parse) yield是提交的意思。callback是一個回調(diào)函數(shù)。本句的意思是將新的newurl重新回調(diào)給parse函數(shù)自身缔恳。然后parse函數(shù)收到新的newurl函數(shù)宝剖,解析newurl的網(wǎng)頁代碼。
另外歉甚,Request還可以在請求下一頁解析的時候万细,將本頁的數(shù)據(jù)通過meta傳遞給下一頁。meta是一個字典纸泄。里邊通過key對應(yīng)value來傳遞給下一個回調(diào)對象赖钞。
方法如下:

yield Request(newurl, meta={'key1':'value1','key2':'value2'},callback=self.parse_info)
def parse_info(self,response)  #這里已經(jīng)解析了newurl的網(wǎng)頁代碼,可以獲取新的網(wǎng)頁數(shù)據(jù)
      item1=SevendayItem()  #假定items.py的item名稱是SevendayItem,將它實(shí)例化給item1聘裁,注意item1是一個字典雪营。
      item1['key1']=response.meta['key1']  #response中meta中的key1的value賦予item['key1']
      item1['key2']=response.meta['key2']   #response中meta中的key2的value賦予item['key2']
      .....
      selector=Selector(response)  ##這里已經(jīng)解析了newurl的網(wǎng)頁代碼
      value=selector.xpath('//../..').extract()[0]   #通過xpath獲取newurl網(wǎng)頁的相對應(yīng)的數(shù)據(jù),注意獲取的數(shù)據(jù)需要在后邊加上`.extract`衡便,要不提取不出來  
      item1['key3']=value    #value賦予 item1['key3']
      yield item1   提交item1

yield item1提交最終的數(shù)據(jù)給items.py,如果還有數(shù)據(jù)在下一級網(wǎng)頁献起,可以創(chuàng)建新的url,然后將item1的值賦予meta,繼續(xù)請求新的url回調(diào)下一個parse_**

yield Request(新的url,meta={},callback=self.parse_**)
def parse_**(self,response)

“7日熱點(diǎn)”遇到BUG的解決處理

由于打賞數(shù)據(jù)是異步加載砰诵,需要在界面中用正則表達(dá)式提取id征唬,然后重新構(gòu)造新的reward_rul,由于是json網(wǎng)頁茁彭,所以需要用方法json.load解析網(wǎng)頁总寒,取出我們要rewards_count

Paste_Image.png

Paste_Image.png

以上2個圖可以看到reward_url是在Request URL中,加載后的數(shù)據(jù)是在下圖中的rewards_count:8
我剛開始做的時候和單線程爬蟲一樣理肺,構(gòu)造如下的reward_url:
rewards_url = ['http://www.reibang.com/notes/{}/rewards.count=20'.format(str(id))][0]
然后將它提交摄闸,回調(diào)給下一個parse_info函數(shù)。
我在解析parse_info的時候妹萨,提取不出reward_count年枕,生成的CSV文件是空的。于是打斷點(diǎn)進(jìn)行調(diào)試:運(yùn)行debug時候乎完,系統(tǒng)提示如下:

20170426_004111.jpg

中間有個DEBUG Forbidden by robots.txt 熏兄,然后去網(wǎng)上查找資料,有人說關(guān)閉scrapy自帶的ROBOTSTXT_OBEY功能树姨,在setting找到這個變量摩桶,設(shè)置為False即可解決。

# Obey robots.txt rules
ROBOTSTXT_OBEY = False

然后再調(diào)試帽揪,還是有問題硝清,如下:

11

于是 想起來可能是因為這個reward_url網(wǎng)頁出錯,但是里邊的json數(shù)據(jù)還是有的转晰,嘗試改一下reward_url地址中芦拿?count=20改為.json如下:

 reward_url = ['http://www.reibang.com/notes/{}/rewards.json'.format(str(id))]

運(yùn)行成功士飒!
專題也是異步加載,所以方法和打賞數(shù)據(jù)處理一樣蔗崎。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末酵幕,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子蚁趁,更是在濱河造成了極大的恐慌裙盾,老刑警劉巖实胸,帶你破解...
    沈念sama閱讀 211,123評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件他嫡,死亡現(xiàn)場離奇詭異,居然都是意外死亡庐完,警方通過查閱死者的電腦和手機(jī)钢属,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,031評論 2 384
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來门躯,“玉大人淆党,你說我怎么就攤上這事⊙攘梗” “怎么了染乌?”我有些...
    開封第一講書人閱讀 156,723評論 0 345
  • 文/不壞的土叔 我叫張陵,是天一觀的道長懂讯。 經(jīng)常有香客問我荷憋,道長,這世上最難降的妖魔是什么褐望? 我笑而不...
    開封第一講書人閱讀 56,357評論 1 283
  • 正文 為了忘掉前任勒庄,我火速辦了婚禮,結(jié)果婚禮上瘫里,老公的妹妹穿的比我還像新娘实蔽。我一直安慰自己,他們只是感情好谨读,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,412評論 5 384
  • 文/花漫 我一把揭開白布局装。 她就那樣靜靜地躺著,像睡著了一般劳殖。 火紅的嫁衣襯著肌膚如雪铐尚。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,760評論 1 289
  • 那天闷尿,我揣著相機(jī)與錄音塑径,去河邊找鬼。 笑死填具,一個胖子當(dāng)著我的面吹牛统舀,可吹牛的內(nèi)容都是我干的匆骗。 我是一名探鬼主播,決...
    沈念sama閱讀 38,904評論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼誉简,長吁一口氣:“原來是場噩夢啊……” “哼碉就!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起闷串,我...
    開封第一講書人閱讀 37,672評論 0 266
  • 序言:老撾萬榮一對情侶失蹤瓮钥,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后烹吵,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體碉熄,經(jīng)...
    沈念sama閱讀 44,118評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,456評論 2 325
  • 正文 我和宋清朗相戀三年肋拔,在試婚紗的時候發(fā)現(xiàn)自己被綠了锈津。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,599評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡凉蜂,死狀恐怖琼梆,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情窿吩,我是刑警寧澤茎杂,帶...
    沈念sama閱讀 34,264評論 4 328
  • 正文 年R本政府宣布,位于F島的核電站纫雁,受9級特大地震影響煌往,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜先较,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,857評論 3 312
  • 文/蒙蒙 一携冤、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸敬肚。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,731評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至癌幕,卻和暖如春衙耕,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背勺远。 一陣腳步聲響...
    開封第一講書人閱讀 31,956評論 1 264
  • 我被黑心中介騙來泰國打工橙喘, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人胶逢。 一個月前我還...
    沈念sama閱讀 46,286評論 2 360
  • 正文 我出身青樓厅瞎,卻偏偏與公主長得像饰潜,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子和簸,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,465評論 2 348

推薦閱讀更多精彩內(nèi)容