20、 Python快速開發分佈式搜索引擎Scrapy精講—編寫spiders爬蟲文件循環抓取內容

百度雲搜索,搜各種資料:http://bdy.lqkweb.com

搜網盤,搜各種資料:http://www.swpan.cn

編寫spiders爬蟲文件循環抓取內容

Request()方法,將指定的url地址添加到下載器下載頁面,兩個必須參數,
  參數:
  url='url'
  callback=頁面處理函數
  使用時需要yield Request()

parse.urljoin()方法,是urllib庫下的方法,是自動url拼接,如果第二個參數的url地址是相對路徑會自動與第一個參數拼接

# -*- coding: utf-8 -*-
import scrapy
from scrapy.http import Request                             #導入url返回給下載器的方法
from urllib import parse                                    #導入urllib庫裏的parse模塊

class PachSpider(scrapy.Spider):
    name = 'pach'
    allowed_domains = ['blog.jobbole.com']                  #起始域名
    start_urls = ['http://blog.jobbole.com/all-posts/']     #起始url

    def parse(self, response):
        """
        獲取列表頁的文章url地址,交給下載器
        """
        #獲取當前頁文章url
        lb_url = response.xpath('//a[@class="archive-title"]/@href').extract()  #獲取文章列表url
        for i in lb_url:
            # print(parse.urljoin(response.url,i))                                             #urllib庫裏的parse模塊的urljoin()方法,是自動url拼接,如果第二個參數的url地址是相對路徑會自動與第一個參數拼接
            yield Request(url=parse.urljoin(response.url, i), callback=self.parse_wzhang)      #將循環到的文章url添加給下載器,下載後交給parse_wzhang回調函數

        #獲取下一頁列表url,交給下載器,返回給parse函數循環
        x_lb_url = response.xpath('//a[@class="next page-numbers"]/@href').extract()         #獲取下一頁文章列表url
        if x_lb_url:
            yield Request(url=parse.urljoin(response.url, x_lb_url[0]), callback=self.parse)     #獲取到下一頁url返回給下載器,回調給parse函數循環進行

    def parse_wzhang(self,response):
        title = response.xpath('//div[@class="entry-header"]/h1/text()').extract()           #獲取文章標題
        print(title)

image

Request()函數在返回url時,同時可以通過meta屬性返回一個自定義字典給回調函數

# -*- coding: utf-8 -*-
import scrapy
from scrapy.http import Request                             #導入url返回給下載器的方法
from urllib import parse                                    #導入urllib庫裏的parse模塊
from adc.items import AdcItem                               #導入items數據接收模塊的接收類

class PachSpider(scrapy.Spider):
    name = 'pach'
    allowed_domains = ['blog.jobbole.com']                  #起始域名
    start_urls = ['http://blog.jobbole.com/all-posts/']     #起始url

    def parse(self, response):
        """
        獲取列表頁的文章url地址,交給下載器
        """
        #獲取當前頁文章url
        lb = response.css('div .post.floated-thumb')  #獲取文章列表區塊,css選擇器
        # print(lb)
        for i in lb:
            lb_url = i.css('.archive-title ::attr(href)').extract_first('')     #獲取區塊裏文章url
            # print(lb_url)

            lb_img = i.css('.post-thumb img ::attr(src)').extract_first('')     #獲取區塊裏文章縮略圖
            # print(lb_img)

            yield Request(url=parse.urljoin(response.url, lb_url), meta={'lb_img':parse.urljoin(response.url, lb_img)}, callback=self.parse_wzhang)      #將循環到的文章url添加給下載器,下載後交給parse_wzhang回調函數

        #獲取下一頁列表url,交給下載器,返回給parse函數循環
        x_lb_url = response.css('.next.page-numbers ::attr(href)').extract_first('')         #獲取下一頁文章列表url
        if x_lb_url:
            yield Request(url=parse.urljoin(response.url, x_lb_url), callback=self.parse)     #獲取到下一頁url返回給下載器,回調給parse函數循環進行

    def parse_wzhang(self,response):
        title = response.css('.entry-header h1 ::text').extract()           #獲取文章標題
        # print(title)

        tp_img = response.meta.get('lb_img', '')                            #接收meta傳過來的值,用get獲取防止出錯
        # print(tp_img)

        shjjsh = AdcItem()                                                                   #實例化數據接收類
        shjjsh['title'] = title                                                              #將數據傳輸給items接收模塊的指定類
        shjjsh['img'] = tp_img

        yield shjjsh                                #將接收對象返回給pipelines.py處理模塊
    • *

Scrapy內置圖片下載器使用

Scrapy給我們內置了一個圖片下載器在crapy.pipelines.images.ImagesPipeline,專門用於將爬蟲抓取到圖片url後將圖片下載到本地

第一步、爬蟲抓取圖片URL地址後,填充到 items.py文件的容器函數

  爬蟲文件

# -*- coding: utf-8 -*-
import scrapy
from scrapy.http import Request                             #導入url返回給下載器的方法
from urllib import parse                                    #導入urllib庫裏的parse模塊
from adc.items import AdcItem                               #導入items數據接收模塊的接收類

class PachSpider(scrapy.Spider):
    name = 'pach'
    allowed_domains = ['blog.jobbole.com']                  #起始域名
    start_urls = ['http://blog.jobbole.com/all-posts/']     #起始url

    def parse(self, response):
        """
        獲取列表頁的文章url地址,交給下載器
        """
        #獲取當前頁文章url
        lb = response.css('div .post.floated-thumb')  #獲取文章列表區塊,css選擇器
        # print(lb)
        for i in lb:
            lb_url = i.css('.archive-title ::attr(href)').extract_first('')     #獲取區塊裏文章url
            # print(lb_url)

            lb_img = i.css('.post-thumb img ::attr(src)').extract_first('')     #獲取區塊裏文章縮略圖
            # print(lb_img)

            yield Request(url=parse.urljoin(response.url, lb_url), meta={'lb_img':parse.urljoin(response.url, lb_img)}, callback=self.parse_wzhang)      #將循環到的文章url添加給下載器,下載後交給parse_wzhang回調函數

        #獲取下一頁列表url,交給下載器,返回給parse函數循環
        x_lb_url = response.css('.next.page-numbers ::attr(href)').extract_first('')         #獲取下一頁文章列表url
        if x_lb_url:
            yield Request(url=parse.urljoin(response.url, x_lb_url), callback=self.parse)     #獲取到下一頁url返回給下載器,回調給parse函數循環進行

    def parse_wzhang(self,response):
        title = response.css('.entry-header h1 ::text').extract()           #獲取文章標題
        # print(title)

        tp_img = response.meta.get('lb_img', '')                            #接收meta傳過來的值,用get獲取防止出錯
        # print(tp_img)

        shjjsh = AdcItem()                                                                   #實例化數據接收類
        shjjsh['title'] = title                                                              #將數據傳輸給items接收模塊的指定類
        shjjsh['img'] = [tp_img]

        yield shjjsh                                #將接收對象返回給pipelines.py處理模塊

第二步、設置 items.py 文件的容器函數,接收爬蟲獲取到的數據填充

# -*- coding: utf-8 -*-

# Define here the models for your scraped items
#
# See documentation in:
# http://doc.scrapy.org/en/latest/topics/items.html

import scrapy

#items.py,文件是專門用於,接收爬蟲獲取到的數據信息的,就相當於是容器文件

class AdcItem(scrapy.Item):    #設置爬蟲獲取到的信息容器類
    title = scrapy.Field()     #接收爬蟲獲取到的title信息
    img = scrapy.Field()       #接收縮略圖
    img_tplj = scrapy.Field()  #圖片保存路徑

第三步、在pipelines.py使用crapy內置的圖片下載器

1、首先引入內置圖片下載器

2、自定義一個圖片下載內,繼承crapy內置的ImagesPipeline圖片下載器類

3、使用ImagesPipeline類裏的item_completed()方法獲取到圖片下載後的保存路徑

4、在settings.py設置文件裏,註冊自定義圖片下載器類,和設置圖片保存路徑

# -*- coding: utf-8 -*-

# Define your item pipelines here
#
# Don't forget to add your pipeline to the ITEM_PIPELINES setting
# See: http://doc.scrapy.org/en/latest/topics/item-pipeline.html
from scrapy.pipelines.images import ImagesPipeline  #導入圖片下載器模塊

class AdcPipeline(object):                      #定義數據處理類,必須繼承object
    def process_item(self, item, spider):       #process_item(item)爲數據處理函數,接收一個item,item裏就是爬蟲最後yield item 來的數據對象
        print('文章標題是:' + item['title'][0])
        print('文章縮略圖url是:' + item['img'][0])
        print('文章縮略圖保存路徑是:' + item['img_tplj'])  #接收圖片下載器填充的,圖片下載後的路徑

        return item

class imgPipeline(ImagesPipeline):                      #自定義一個圖片下載內,繼承crapy內置的ImagesPipeline圖片下載器類
    def item_completed(self, results, item, info):      #使用ImagesPipeline類裏的item_completed()方法獲取到圖片下載後的保存路徑
        for ok, value in results:
            img_lj = value['path']     #接收圖片保存路徑
            # print(ok)
            item['img_tplj'] = img_lj  #將圖片保存路徑填充到items.py裏的字段裏
        return item                    #將item給items.py 文件的容器函數

    #注意:自定義圖片下載器設置好後,需要在

在settings.py設置文件裏,註冊自定義圖片下載器類,和設置圖片保存路徑

IMAGES_URLS_FIELD 設置要下載圖片的url地址,一般設置的items.py裏接收的字段
IMAGES_STORE 設置圖片保存路徑

# Configure item pipelines
# See http://scrapy.readthedocs.org/en/latest/topics/item-pipeline.html
ITEM_PIPELINES = {
   'adc.pipelines.AdcPipeline': 300,  #註冊adc.pipelines.AdcPipeline類,後面一個數字參數表示執行等級,
   'adc.pipelines.imgPipeline': 1,    #註冊自定義圖片下載器,數值越小,越優先執行
}

IMAGES_URLS_FIELD = 'img'                             #設置要下載圖片的url字段,就是圖片在items.py裏的字段裏
lujin = os.path.abspath(os.path.dirname(__file__))
IMAGES_STORE = os.path.join(lujin, 'img')             #設置圖片保存路徑

image
【轉載自:http://www.lqkweb.com

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