1. 程式人生 > >Scrapy基礎(十三)————ItemLoader的簡單使用

Scrapy基礎(十三)————ItemLoader的簡單使用

_id path default filder sin 重載 自己的 pid 自定義

ItemLoader的簡單使用:目的是解決在爬蟲文件中代碼結構雜亂,無序,可讀性差的缺點

經過之前的基礎,我們可以爬取一些不用登錄,沒有Ajax的,等等其他的簡單的爬蟲
回顧我們的代碼,是不是有點冗長,將所需字段通過xpath或者css解析出來,再自定義語句(還不是函數中)
進行清洗;然後再裝入Item中,有沒有這樣一種方法:從Item中可以直接清洗豈不是很簡單
今天就學習 ItemLoader這樣一種對戲,簡單代碼,可讀增強

思路:

1,創建一個ItemLoad對象

2,通過該對象的add_css或者add_xpath或者add_value方法將解析語句裝入ItemLoader

3,在Item.py中在Filder()中調用函數,用來清洗,處理數據
4,artical_item = item_loader.load_item() 調用這個對象的此方法,寫入到Item中

具體代碼:

在爬蟲文件中:

 1 #先引入
 2 from ArticalSpider.items import JobboleArticalItem,ArticalItemLoader
 3         #使用Itemloader來簡化這個解析,裝入Item這個過程,使得代碼量減少
 4         #先創建一個itemLoader()這樣一個對象,不需解析list第一個等問題
5 #這裏的ArticalItemLoader是繼承了itemloader,並重寫了部分功能,實現定制 6 item_loader = ArticalItemLoader(item=JobboleArticalItem(), response=response) 7 #使用ItemLoader這個對象的xpath解析器 8 item_loader.add_xpath("title",/html//div[@class="entry-header"]/h1/text()) 9 #使用get_value()直接從response中選取內容
10 item_loader.add_value("url_object_id",get_md5(response.url)) 11 item_loader.add_xpath("add_time", /html//p[@class="entry-meta-hide-on-mobile"]/text()) 12 item_loader.add_value("url", response.url) 13 item_loader.add_value("front_image_url", [front_image_url]) 14 item_loader.add_value("front_image_url2",front_image_url) 15 item_loader.add_xpath("tags",/html//p[@class="entry-meta-hide-on-mobile"]/a/text()) 16 item_loader.add_xpath("comment_num",//span[@class="btn-bluet-bigger href-style hide-on-480"]/text()) 17 item_loader.add_xpath("fav_num",//span[contains(@class,"bookmark-btn")]/text()) 18 item_loader.add_xpath("like_num",//span[contains(@class,"vote-post-up")]/h10/text()) 19 item_loader.add_xpath("content",//div[@class="entry"]) 20 #裝入Item 21 artical_item = item_loader.load_item() 22 23 yield artical_item


在Item.py中

 1 #繼承ItemLoader這個方法,並自定義自己的方法(屬性)
 2 class ArticalItemLoader(ItemLoader):
 3     #實現之前的extract_first()方法
 4     #這裏只是重載這個屬性,設置為只選取第一個值
 5     default_output_processor = TakeFirst()
 6 
 7 #以下將之前的各種清洗語句整合到函數中
 8 def add_title_jobbole(value):
 9     return value+"---jobbole"
10 
11 def get_time(value):
12     #這個好像更改不了
13     try:
14         add_time = datetime.datetime.strptime(value,"%Y/%m/%d").data()
15     except Exception as e:
16         print(e)
17         add_time = datetime.datetime.now().date()
18     return add_time
19 
20 def get_tags(value):
21     tag_list = [x for x in value if not str(x).strip().endswith("評論") ]
22 
23     return tag_list
24 def get_comment_num(value):
25     re_comment = re.match(".*(\d+).*",value)
26     if re_comment:
27         comment_num = int(re_comment.group(1))
28     else:
29         comment_num = 0
30     return comment_num
31 def get_fav_num(value):
32     re_fav_num = re.match(".*(\d+).*",value)
33     if re_fav_num:
34         fav_num =  int(re_fav_num.group(1))
35     else:
36         fav_num = 0
37     return fav_num
38 #小技巧:在出IteaLoad時,將之前進入的類型按原先的返回,怎麽進入怎麽返回
39 def get_value(value):
40     return value
41 class JobboleArticalItem(scrapy.Item):
42     title = scrapy.Field(
43     #調用方法,為傳進的數據字段進行清洗,調用外部的方法
44         #input_processor 方法是將進入的數據進行調用函數清洗
45         #MapCompose 調用函數名
46         input_processor = MapCompose(add_title_jobbole)
47     )
48     add_time = scrapy.Field(
49         input_processor = MapCompose(get_time),
50         #只獲取傳入Item的這個列表中的第一個值作為Item的值
51         #但是要是字段太多,都得寫下面這個語句,豈不麻煩,所以可以繼承ItemLoader這個類,完成自己類
52         #TakeFirsr()就是 extrct_first()
53         output_processor = TakeFirst()
54     )
55     url = scrapy.Field()
56     content = scrapy.Field()
57     #不同url長度不同,通過md5統一長度
58     url_object_id = scrapy.Field()
59 
60     front_image_url = scrapy.Field(
61         #自定義的類之後,所有的Item都默認了list的第一個值,但傳入下載圖片的管道時會報錯,因為下載圖片的Item為list
62         #出去ItemLoader時處理數據的方法
63         output_processor = MapCompose(get_value)
64     )
65     front_image_url2 = scrapy.Field()
66     #url本地存放路徑
67     front_image_path = scrapy.Field()
68 
69     tags = scrapy.Field(
70         input_processor = MapCompose(get_tags),
71         #使用processor自帶的Join拼接方法
72         output_processor = Join(",")
73     )
74     comment_num = scrapy.Field(
75         input_processor = MapCompose(get_comment_num)
76     )
77     fav_num = scrapy.Field(
78         input_processor = MapCompose(get_fav_num)
79     )
80     like_num = scrapy.Field(
81 
82     )

註意:
  在保存要下載的圖片的URL時,保存在Item中的應該是List;否則報錯:

  raise ValueError: Missing scheme in request url: h

  原因:1,我們繼承了Itemloader並重寫了default_output_processor = TakeFirst();所以,這時圖片URL為str

  解決辦法:

    自定義方法:將怎樣進來的value怎樣出去(因為進來的是list)  

  技術分享

技術分享

Scrapy基礎(十三)————ItemLoader的簡單使用