iT邦幫忙

第 11 屆 iThome 鐵人賽

DAY 27
1
AI & Data

爬蟲在手、資料我有 - 30 天 Scrapy 爬蟲實戰系列 第 27

【Day 26】Scrapy 的結構化資料 - Item

  • 分享至 

  • twitterImage
  •  

在前幾天的爬蟲中,我們都是以 Python dict 的結構在儲存爬取結果,隨著爬蟲數量增加,會在越來越多的程式中使用到相同的結構來儲存資料,但同時也容易在不同爬蟲中打錯欄位名稱(例如 title 打成 titl)或者回傳結構不同的項目。好在 Scrapy 有提供一個 Item 類別,讓我們能先定義好爬取結果的欄位。

定義 Item

建立好專案後,專案目錄中會有一個 items.py 檔案,其中有 Scrapy 根據專案名稱自動建立的 IthomeCrawlersItem 類別,通常我會把自訂的項目類別也放在這個檔案中。每個自訂的項目都要繼承 scrapy.Item 類別,欄位則以 scrapy.Field() 來定義。

import scrapy

class IthomeCrawlersItem(scrapy.Item):
    # define the fields for your item here like:
    # name = scrapy.Field()
    pass

接下來在 item.py 檔案中加入代表文章資料的類別 IthomeArticleItem,並分別定義好每個欄位:

class IthomeArticleItem(scrapy.Item):
    url = scrapy.Field()
    title = scrapy.Field()
    author = scrapy.Field()
    publish_time = scrapy.Field()
    tags = scrapy.Field()
    content = scrapy.Field()
    view_count = scrapy.Field()

使用 Item 類別

定義好 Item 後就可以在程式中使用這個類別了,使用的方式跟 dict 幾乎一樣:

import ithome_crawlers.items as items

# 初始化實例
item = item.IthomeArticleItem()
item['url'] = 'https://ithelp.ithome.com.tw/articles/10215484'
# 打錯欄位名稱會報錯:KeyError: 'IthomeArticleItem does not support field: titl'
item['titl'] = '【Day 0】前言'
item['title'] = '【Day 0】前言'

print(item)

https://ithelp.ithome.com.tw/upload/images/20191011/20107875mxPoayqHHG.png

再來把昨天的爬蟲修改為使用剛剛定義的 IthomeArticleItem 類別,完整程式碼可以到 gist 查看。

其實就是把原本的:

article = {
    'url': response.url,
    'title': title,
    'author': author,
    'publish_time': published_time,
    'tags': ','.join(tags),
    'content': content,
    'view_count': view_count
}

改成:

article = items.IthomeArticleItem()
article['url'] = response.url
article['title'] = title
article['author'] = author
article['publish_time'] = published_time
article['tags'] = ''.join(tags)
article['content'] = content
article['view_count'] = view_count

參考資料


上一篇
【Day 25】用 Scrapy 爬取 iT 邦幫忙的技術文章
下一篇
【Day 27】在 Scrapy 中處理爬取結果 - Item Pipelines
系列文
爬蟲在手、資料我有 - 30 天 Scrapy 爬蟲實戰33
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言