日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

爬虫学习笔记(七)——Scrapy框架(二):Scrapy shell、选择器

發布時間:2025/3/21 编程问答 20 豆豆
生活随笔 收集整理的這篇文章主要介紹了 爬虫学习笔记(七)——Scrapy框架(二):Scrapy shell、选择器 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

一、Scrapy shell

scrapy shell的作用是用于調試,在項目目錄下輸入scrapy shell start_urls (start_urls:目標url)得到下列信息:

scrapy shell 會自動加載settings里的配置,即robots協議,請求頭等都可以加載,從而發起請求可以得到正確的響應信息。

[s] Available Scrapy objects: [s] scrapy scrapy module (contains scrapy.Request, scrapy.Selector, etc) #scrapy 模塊 [s] crawler <scrapy.crawler.Crawler object at 0x000002624C415F98> #爬蟲對象 [s] item {} #item對象 [s] request <GET https://movie.douban.com/top250> # 請求對象 [s] response <200 https://movie.douban.com/top250> #響應對象 [s] settings <scrapy.settings.Settings object at 0x000002624C415EB8> #配置文件 [s] spider <DefaultSpider 'default' at 0x2624c8ed3c8> #spider文件 [s] Useful shortcuts: [s] fetch(url[, redirect=True]) Fetch URL and update local objects (by default, redirects are followed) #通過url 獲取response [s] fetch(req) Fetch a scrapy.Request and update local objects #通過請求對象 獲取response [s] shelp() Shell help (print this help) #列出命令 [s] view(response) View response in a browser #response 界面 本地瀏覽器環境下使用

Scrapy shell 本質上就是個普通的python shell
只不過提供了一些需要使用的對象,快捷方法便于我們調試。

  • 快捷方法:
    shelp()
    fetch(url[,redirect=True])
    fetch(request)
    view(response)
  • scrapy 對象:
    crawler
    spider
    request
    response
    setting

二、Scrapy 選擇器

  • Scrapy提供基于lxml庫的解析機制,它們被稱為選擇器。
    因為,它們“選擇”由XPath或CSS表達式指定的HTML文檔的某部分。
    Scarpy選擇器的API非常小,且非常簡單。

  • 選擇器提供2個方法來提取標簽
    xpath() 基于xpath的語法規則
    css() 基于css選擇器的語法規則

    快捷方式
    response.xpath()
    response.css()
    它們返回的選擇器列表

    提取文本:
    selector.extract() 返回文本列表
    selector.extract_first() 返回第一個selector的文本,沒有返回None

  • 嵌套選擇器
    ①有時候我們獲取標簽需要多次調用選擇方法(.xpath()或.css())
    例如:response.css(‘img’).xpath(’@src’)
    ②Selector還有一個.re()方法使用正則表達式提取數據的方法。它返回字符串。它一般使用在xpath(),css()方法之后,用來過濾文本數據。
    re_first()用來返回第一個匹配的字符串。

示例:

html_str=""" <div class="info"><div class="hd"><a href="https://movie.douban.com/subject/1292052/" class=""><span class="title">肖申克的救贖</span><span class="title">&nbsp;/&nbsp;The Shawshank Redemption</span><span class="other">&nbsp;/&nbsp;月黑高飛(港) / 刺激1995(臺)</span></a><span class="playable">[可播放]</span></div><div class="bd"><p class="">導演: 弗蘭克·德拉邦特 Frank Darabont&nbsp;&nbsp;&nbsp;主演: 蒂姆·羅賓斯 Tim Robbins /...<br>1994&nbsp;/&nbsp;美國&nbsp;/&nbsp;犯罪 劇情</p><div class="star"><span class="rating5-t"></span><span class="rating_num" property="v:average">9.7</span><span property="v:best" content="10.0"></span><span>1980500人評價</span></div><p class="quote"><span class="inq">希望讓人自由。</span></p></div> </div> </div> """ from scrapy.selector import Selector #1.通過text 參數來構造對象 select = Selector(text=html_str) print(select.xpath('//div[@class="info"]/div/a/span/text()')[0].extract()) print(select.xpath('./body/div[@class="info"]//div/a/span/text()').extract()[0]) print(select.xpath('//div[@class="info"]//div/a/span/text()').extract_first())# 2.通過 response 構造selector對象 from scrapy.http import HtmlResponse response = HtmlResponse(url='http://exc.com',body=html_str.encode()) Selector(response=response) print(response.selector.xpath('//div[@class="info"]//div/a/span/text()').extract()[0]) print(response.xpath('//div[@class="info"]//div/a/span/text()').extract()[0])#3.嵌套表達式 selector 可以任意使用 css xpath re print(response.css("a").xpath('./span[1]/text()').extract()[0]) print(response.css("a").xpath('./span[1]/text()').re("的..")[0]) print(response.css("a").xpath('./span[1]/text()').re_first("的.."))

三、scrapy.Spider

spider 的名稱 name
一個字符串,用于定義此蜘蛛的名稱。蜘蛛名稱是Scrapy如何定位(并實例化)蜘蛛,因此它必須是唯一的。這是最重要的蜘蛛屬性,它是必需的。

起始urls
蜘蛛將開始爬取的URL列表。因此,下載的第一頁將是此處列出的頁面。后續Request將從起始URL中包含的數據連續生成。

自定義設置
運行此蜘蛛時將覆蓋項目范圍的設置。必須將其定義為類屬性,因為在實例化之前更新了設置。

class Spider(object_ref):"""Base class for scrapy spiders. All spiders must inherit from thisclass."""name: Optional[str] = Nonecustom_settings: Optional[dict] = Nonedef __init__(self, name=None, **kwargs):if name is not None:self.name = nameelif not getattr(self, 'name', None):raise ValueError(f"{type(self).__name__} must have a name")self.__dict__.update(kwargs)if not hasattr(self, 'start_urls'):self.start_urls = []

logger
使用Spider創建的Python日志器。您可以使用它來發送日志消息。

@property def logger(self):logger = logging.getLogger(self.name)return logging.LoggerAdapter(logger, {'spider': self})def log(self, message, level=logging.DEBUG, **kw):"""Log the given message at the given log levelThis helper wraps a log call to the logger within the spider, but youcan use it directly (e.g. Spider.logger.info('msg')) or use any otherPython logger too."""self.logger.log(level, message, **kw)

from_crawler
這是Scrapy用于創建spider的類方法。一般不用覆蓋。

@classmethod def from_crawler(cls, crawler, *args, **kwargs):spider = cls(*args, **kwargs)spider._set_crawler(crawler)return spiderdef _set_crawler(self, crawler):self.crawler = crawlerself.settings = crawler.settingscrawler.signals.connect(self.close, signals.spider_closed)

start_requests() 開始請求
此方法必須返回一個iterable,其中包含第一個要爬網的請求。它只會被調用一次

def start_requests(self):cls = self.__class__if not self.start_urls and hasattr(self, 'start_url'):raise AttributeError("Crawling could not start: 'start_urls' not found ""or empty (but found 'start_url' attribute instead, ""did you miss an 's'?)")if method_is_overridden(cls, Spider, 'make_requests_from_url'):warnings.warn("Spider.make_requests_from_url method is deprecated; it ""won't be called in future Scrapy releases. Please ""override Spider.start_requests method instead (see %s.%s)." % (cls.__module__, cls.__name__),)for url in self.start_urls:yield self.make_requests_from_url(url)else:for url in self.start_urls:yield Request(url, dont_filter=True)

parse 默認回調函數方法
這是Scrapy在其請求未指定回調時處理下載的響應時使用的默認回調

def parse(self, response):raise NotImplementedError('{}.parse callback is not defined'.format(self.__class__.__name__))

close 關閉spider
spider關閉時調用


四、小案例:次級頁面抓取及數據傳遞拼接(豆瓣電影)

基于上一篇博客(小爬蟲學習(六)——Scrapy框架(一))的案例,我們在其基礎上爬取每個電影次級頁面的“電影詳情”,最終存儲到excel表格里。

spider文件

(我的文件名:db)

import scrapy import re from ..items import Db250Itemclass DbSpider(scrapy.Spider): #繼承基礎類name = 'db' #爬蟲文件名字# allowed_domains = ['movie.douban.com']start_urls = ['https://movie.douban.com/top250'] #初始url 必須存在page = 0def parse(self, response): #解析函數 處理響應數據all_mes = response.xpath('//div[@class="info"]')for mes in all_mes:#電影名字film_name = mes.xpath('./div/a/span[1]/text()')[0].extract()#評分score = mes.xpath('./div/div/span[2]/text()')[0].extract()#導演信息director = mes.xpath('./div/p/text()')[0].extract().strip()#使用管道存儲item = Db250Item()item['film_name'] = film_nameitem['score'] = scoreitem['director'] = director# 次級頁面的url 電影簡介 detail_url = mes.xpath('./div/a/@href').extract()[0]yield scrapy.Request(detail_url,callback=self.get_detail,meta={'info':item}) #參數的傳遞拼接的關鍵參數是 meta參數#發送新一頁的請求#構造urlself.page += 1if self.page == 3: #我們就先構造3頁returnpage_url = 'https://movie.douban.com/top250?start={}&filter='.format(self.page * 25)yield scrapy.Request(page_url)def get_detail(self,response):items = Db250Item()#解析詳情頁的response#1.meta 會跟隨response 一塊返回 2.通過response.meta接收 3.通過update 添加到新的item對象中info = response.meta["info"]items.update(info)#簡介內容detail= response.xpath('//div[@class="indent"]//span[@property="v:summary"]/text()').extract()[0].strip()items['detail'] = detailyield items

注意:

目標數據: 電影信息+ 獲取電影簡介數據 請求流程: ①訪問一級頁面,提取電影信息+次級頁面的url ②訪問次級頁面url 從次級的數據中提取電影簡介 存儲的問題:數據沒有次序需要使用 meta傳參保證同一電影的信息在一起

items文件

import scrapy class Db250Item(scrapy.Item):# define the fields for your item here like:# name = scrapy.Field()film_name = scrapy.Field()score = scrapy.Field()director = scrapy.Field()detail = scrapy.Field()

pipelines 文件

將數據寫入excel表格

import json import pandas as pd from itemadapter import ItemAdapterclass Db250Pipeline:def open_spider(self,spider): #函數名字是固定的self.filmlist = []def process_item(self, item, spider):self.filmlist.append(dict(item))return itemdef close_spider(self,spider): #函數名字是固定的df = pd.DataFrame(self.filmlist)df.to_csv('film.csv')

settings 文件

設置robots協議,添加全局請求頭,開啟管道
(只修改這三部分就行了)

ROBOTSTXT_OBEY = FalseDEFAULT_REQUEST_HEADERS = {'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8','Accept-Language': 'en','User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.114 Safari/537.36 Edg/91.0.864.54' }ITEM_PIPELINES = {'db250.pipelines.Db250Pipeline': 300, }

結果:

總結

以上是生活随笔為你收集整理的爬虫学习笔记(七)——Scrapy框架(二):Scrapy shell、选择器的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。