采集川大公管學(xué)院教師信息

一、采集前的準(zhǔn)備

首先進(jìn)入四川大學(xué)公共管理學(xué)院官網(wǎng),查看其師資隊(duì)伍師資隊(duì)伍板塊對教師信息的陳列方式。未來采集將從這里開始。
從網(wǎng)站陳列的方式可以看到:

教師分為三類:全職教師、客座教師、退休教師、博士后流動(dòng)站。

通過點(diǎn)擊每個(gè)版塊的教師查看具體信息,每個(gè)老師的信息包括(教師的圖片包含進(jìn)入具體頁的鏈接):

姓名、職稱、專業(yè)、郵箱。
姓名、職稱、簡短簡歷、代表性研究成果、獲獎(jiǎng)情況、科研項(xiàng)目、人才培養(yǎng)

師資隊(duì)伍開始采集全職教師的姓名、職稱、專業(yè)、郵箱、圖片,并進(jìn)行翻頁。對每個(gè)老師而言,進(jìn)入詳細(xì)頁面繼續(xù)采集簡短簡歷、代表性研究成果、獲獎(jiǎng)情況、科研項(xiàng)目、人才培養(yǎng)的內(nèi)容。

對于部分教師,其信息沒有上傳到官網(wǎng).應(yīng)考慮沒有信息的默認(rèn)采集格式。

二、開始采集

在這一次才采集過程,依然按照scrapy教程的步驟進(jìn)行采集實(shí)踐。
首先建立這一次的采集項(xiàng)目,項(xiàng)目名稱是jsinfo(教師信息):

jsinfo

可以看到在jsinfo項(xiàng)目之下的內(nèi)容目錄呈以下結(jié)構(gòu):


jsinfo項(xiàng)目的內(nèi)容目錄

在正式采集之前,現(xiàn)在items.py這個(gè)文件中定義即將采集的字段(實(shí)際上定義了之后,感覺太難也沒用)。


items.py定義采集字段

在spiders下建立jsinfo_spider.py文件,開始寫第一個(gè)爬蟲(這部分并沒有什么意義。。。)。
import scrapy


class JsInfoSpider(scrapy.Spider):
   name = "infos"

   def start_requests(self):
       urls = [
           'http://ggglxy.scu.edu.cn/index.php?c=article&a=type&tid=18'
       ]
       for url in urls:
           yield scrapy.Request(url=url, callback=self.parse)

   def parse(self, response):
       page = response.url.split("/")[-2]
       filename = 'infos-%s.html' % page
       with open(filename, 'wb') as f:
           f.write(response.body)
       self.log('Saved file %s' % filename)

然后執(zhí)行infos爬蟲,可以得到師資隊(duì)伍的html文件。
root@iZwz9bmo44a33isf69hxp5Z:~/venv/jsinfo# scrapy crawl infos
接著提取師資隊(duì)伍頁面的部分內(nèi)容,如下:

打開師資隊(duì)伍頁面

提取教師名字

提取教師的職稱

這時(shí)我想繼續(xù)提取教師的專業(yè)以及他們各自的郵箱,這時(shí)發(fā)現(xiàn)專業(yè)與郵箱都相同標(biāo)簽下的文本內(nèi)容,如何在同一標(biāo)簽下分條目抓取內(nèi)容我未遇到過??紤]通過定位p[0],p[1]將同一標(biāo)簽下的字段截?cái)?,試過之后結(jié)果是第一個(gè)字段沒有數(shù)據(jù),而第二個(gè)字段的數(shù)據(jù)都采集下來的數(shù)據(jù)是原本第一個(gè)字段的數(shù)據(jù)。

p標(biāo)簽下的數(shù)據(jù)

于是推測,在這里,數(shù)據(jù)字段是從“1”開始的。修改代碼之后,可以得到正確的結(jié)果。

 'jsmajor': info.xpath("http://div[@class='desc']/p[1]/text()").extract_first(),
                    'jsmail': info.xpath("http://div[@class='desc']/p[2]/text()").extract_first()
p標(biāo)簽數(shù)據(jù)分段
相同標(biāo)簽下的專業(yè)+郵箱

在解決這個(gè)問題之前,我是將專業(yè)和郵箱采集到一起。當(dāng)然還是分開采集更加顯著了。

第一頁采集結(jié)果

這時(shí)爬蟲infos的代碼如下:

    start_urls = [
            'http://ggglxy.scu.edu.cn/index.php?c=article&a=type&tid=18&page_1_page=1'
        ]

    def parse(self, response):
            for info in response.xpath("http://div[@class='r fr']"):
                yield {
                    'jsname': info.xpath("http://h3[@class='mb10']/text()").extract_first(),
                    'jstitle': info.xpath("http://p[@class='color_main f14']/text()").extract_first(),
                    'jsmajormail': info.xpath("http://div[@class='desc']/p/text()").extract(),
                }

第一頁的采集下來了,接下來沒有去采集子頁面的內(nèi)容,打算先實(shí)現(xiàn)翻頁功能。于是,先嘗試用指導(dǎo)文檔中的翻頁設(shè)置:


next_page = response.xpath("http://li[@href]/@href").extract_first()
        if next_page is not None:
            next_page = response.urljoin(next_page)
            yield scrapy.Request(next_page, callback=self.parse)

結(jié)果翻頁是不成功的,或者出現(xiàn)將首頁重復(fù)兩次的情況。多次試驗(yàn),依然失敗。于是考慮到公共管理學(xué)院師資隊(duì)伍就16頁,或許可以以循環(huán)的方式將url全部寫出來。然后照著其他資料提示,改了spider內(nèi)容。

    start_urls = []

    def start_requests(self):
        i = 1
        while i <= 16:
            url = "http://ggglxy.scu.edu.cn/index.php?c=article&a=type&tid=18&page_1_page=%d" % i
            yield self.make_requests_from_url(url)
            i += 1

然后運(yùn)行爬蟲‘infosone’,可以發(fā)現(xiàn)已經(jīng)成功實(shí)現(xiàn)了翻頁。結(jié)果發(fā)現(xiàn)將每個(gè)頁面重復(fù)爬取多次(貌似重復(fù)8次,也是不懂為什么了)。后面嘗試修改代碼以避免重復(fù)頁面抓取,但是始終修改不對。

翻頁結(jié)果1

教師基本信息的顯示的xml

于是我就先把這個(gè)問題放到一邊。然后先去采集詳情頁的內(nèi)容,預(yù)想直接加入基本頁代碼之中,看能不能連接到一起。并且沒有加入翻頁的結(jié)構(gòu),只是在第一頁進(jìn)行試驗(yàn)。

import scrapy


class JsInfoSpider(scrapy.Spider):
    name = "infostwo"
    start_urls = [
        'http://ggglxy.scu.edu.cn/index.php?c=article&a=type&tid=18'
        ]

    def parse(self, response):
            for info in response.xpath('//li[@class="f1"]'):
                yield {
                    'jsname': info.xpath("http://h3[@class='mb10']/text()").extract_first(),
                    'jstitle': info.xpath("http://p[@class='color_main f14']/text()").extract_first(),
                    'jsmajor': info.xpath("http://div[@class='desc']/p[1]/text()").extract_first(),
                    'jsmail': info.xpath("http://div[@class='desc']/p[2]/text()").extract_first()
                }
            for href in response.xpath('//li[@class="f1"]/div[@class="1 f1"]/a/@href').extract():
                yield scrapy.Request(response.urljoin(href),
                                       callback=self.parse_txxinfo)

    @staticmethod
    def parse_txxinfo(self, response):
        for intro in response.xpath('//div[@class="r fr"]'):
            yield {
                'jsname': intro.xpath('h3/text()').extract_first(),
                'jsresume': intro.xpath('div[@class="desc"]/text()').extract_first(),
            }

然而結(jié)果不是想象那樣,我就覺得是我邏輯出了錯(cuò),于是問了其他同學(xué),發(fā)現(xiàn)邏輯差不多。難道是代碼錯(cuò)了,比對了一下,大體機(jī)構(gòu)相似。后來甚至改成相同的,結(jié)果人家的能出來詳情頁結(jié)果,然而我的就是出來不了。不行。。。
然后我就單獨(dú)寫了一個(gè)爬蟲去爬取詳情頁內(nèi)容。因?yàn)樯厦娴难h(huán)url不能 使用,依然采取了教程中的“下一頁”方式。
分頁的代碼:

import scrapy


class JsInfoSpider(scrapy.Spider):
    name = 'infosthree'

    start_urls = ['http://ggglxy.scu.edu.cn/index.php?c=article&a=type&tid=18'
                  ]

    def parse(self, response):
        # follow links to author pages
        for href in response.xpath('//li[@class="f1"]/div[@class="1 f1"]/a/@href').extract():
            yield scrapy.Request(response.urljoin(href),
                                 callback=self.parse)
            # follow pagination links
            next_page = response.xpath('//div[@class="pager cf tc pt10 pb10 mobile_dn"]/li/a/@href').extract_first()
            if next_page is not None:
                next_page = response.urljoin(next_page)
                yield scrapy.Request(next_page, callback=self.parse_moreinfos)

        def parse_moreinfos(self, response):
            def extract_with_xpath(query):
                return response.xpath(query).extract_first ().strip ()
            yield {
                'jsname': extract_with_xpath('//div[@class="r fr"]/h3/text()'),
                'jsresume': extract_with_xpath('//div[@class="r fr"]/div[@class="desc"]/text()'),
            }

不分頁的代碼:

import scrapy


class JsInfoSpider(scrapy.Spider):
    name = 'infosthree'
    start_urls = ['http://ggglxy.scu.edu.cn/index.php?c=article&a=type&tid=18']

    def parse(self, response):
        # follow links to author pages
        for href in response.xpath('//div[@class="1 f1"]/a/@href'):
            yield response.follow(href, self.parse_infosthree)
    @staticmethod
    def parse_infosthree(response):
        def extract_with_xpath(query):
                return response.xpath(query).extract_first().strip()
        yield {
                'jssrc': extract_with_xpath('//div[@class="1 f1"]/img/src'),
                'jsname': extract_with_xpath('//div[@class="r fr"]/h3/text()'),
                'jsresume': extract_with_xpath('//div[@class="r fr"]/div[@class="desc"]/text()'),
         }

結(jié)果依然不行啊。于是決定只是爬取第一頁的詳情頁內(nèi)容看看,這時(shí)發(fā)現(xiàn)反復(fù)報(bào)的是同樣的錯(cuò)。


錯(cuò)誤報(bào)告

頁面不存在?
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容