Scrapy爬取數據案例

Scrapy爬取數據


昨天練習了一個簡單例子,今天進行進一步的學習——爬取同域下的多個網頁。

Tencent 的招聘信息進行爬取:
騰訊招聘

Tencent招聘網站

可以看到需要的信息都在< tbody >下的class爲even和odd< tr > 標籤中。

< tr > 中的需求的數據爲職位名職位鏈接職位人數職位類別工作地點發佈日期

使用xpath可以很容易得到這些數據的獲取方式:
數據集:xpath(“//tr[@class=’even’] | //tr[@class=’odd’]”)
職位名:xpath(“./td[1]/a/text()”)
職位鏈接:xpath(“./td[1]/a/@href”)
職位人數:xpath(“./td[3]/text()”)
職位類別:xpath(“./td[2]/text()”)
工作地點:xpath(“./td[4]/text()”)
發佈日期:xpath(“./td[5]/text()”)

1.爬取方式一

  1. 新建工程Tencent

    scrapy startproject Tencent
    cd myproject

  2. 創建spider

    scrapy genspider Tenspider “tencent.com”

  3. 修改setting

        # Obey robots.txt rules
        ROBOTSTXT_OBEY = False
        ITEM_PIPELINES = {
        'Tencent.pipelines.TencentPipeline': 300,
        }
  4. 編寫管道

    import json 
    class TencentPipeline(object):
        def __init__(self):
            self.f = open("Tencent.json","wb+")
    
        def process_item(self, item, spider):
            content = json.dumps(dict(item),ensure_ascii = False) + ",\n"
            self.f.write(content.encode("utf-8"))
            return item
    
        def colse_spider(self,spider):
            self.f.close()
  5. 編寫item

    import scrapy   
    class TencentItem(scrapy.Item):
        #職位名
        positio_name = scrapy.Field()
        #職位鏈接
        position_link = scrapy.Field()
        #職位類型
        poistion_type = scrapy.Field()
        #招聘的人數
        people_num = scrapy.Field()
        #工作地點
        work_location = scrapy.Field()
        #發佈的時間
        publish_time = scrapy.Field()
        pass
  6. 編寫spider

    import scrapy
    from Tencent.items import TencentItem
    
    class TenspiderSpider(scrapy.Spider):
        #爬蟲名
        name = 'TenSpider'
        #爬蟲的爬取域
        allowed_domains = ['tencent.com']
        #處理翻頁請求
        baseURL="http://hr.tencent.com/position.php?&start="
        #頁面的偏移量,即baseUrl中的start的值
        offset = 0
        #起始的URL列表
        start_urls = [baseURL + str(offset)]
    
        def parse(self, response):
            item = TencentItem()
            #數據集
            node_list = response.xpath("//tr[@class='even'] | //tr[@class='odd']")
            #提取數據,並將其轉換爲utf-8編碼,然後傳入item中
            for node in node_list:
                item["positio_name"] =node.xpath("./td[1]/a/text()").extract()
                item["position_link"] =node.xpath("./td[1]/a/@href").extract()
                item["people_num"] =node.xpath("./td[3]/text()").extract()
                item["work_location"] =node.xpath("./td[4]/text()").extract()
                item["publish_time"] =node.xpath("./td[5]/text()").extract()
                #有類別爲空的情況
                if len(node.xpath("./td[2]/text()")):
                    item["poistion_type"] =node.xpath("./td[2]/text()").extract()
                else:
                    item["poistion_type"] = ""
    
                yield item
    
            if self.offset < 2100:
                self.offset +=10
                url = self.baseURL + str(self.offset)
                yield scrapy.Request(url,callback = self.parse)
    
            pass
  7. 執行spider
    scrapy genspider Tenspider

    爬取時間花了1分半。。
    抓取完成

2.爬取方式二

上面的爬取需要事先確定頁數,一旦頁數發生變換,代碼就得改動,很不方便。這主要是用於無法提取下一頁鏈接的情況。第二種方式是自動提取下一頁鏈接,事先無需知道頁數。

從網頁element中可以看到,下一頁的導航規律:
第一頁的element:
第一頁

最後一頁的element:
最後一頁

可以看出:終止條件爲達到最後一頁,即檢索到id爲next且class爲noactive的< a />標籤。

所以 xpath(“//a[@id=’next’ and @class=’noactive’]”),只要有匹配項就說明符合終止條件了。

如果沒到終止條件,那麼就提取出下一頁的鏈接:
xpath(“//a[@id=’next’]/@href”)

方式二爬取數據

找到將方式一的spider文件中的以下代碼:

if self.offset < 2100:
                self.offset +=10
                url = self.baseURL + str(self.offset)
                yield scrapy.Request(url,callback = self.parse)

替換成:

if len(response.xpath("//a[@id='next' and @class='noactive']")) ==0:
            url = response.xpath("//a[@id='next']/@href").extract()[0]
            yield scrapy.Request("http://hr.tencent.com/" + url,callback = self.parse)

執行spider
爬取完成:
爬取數據2

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