scrapy裡面item傳遞資料後資料不正確的問題

2021-09-21 02:14:18 字數 3535 閱讀 6242

在上篇文章《python3 + scrapy 爬取妹子圖 (meizitu.com)》中,我爬取了妹子圖**的,爬取是按照如下思路的:

通過首頁(爬取標籤名稱tag_name和標籤鏈結tag_href

通過標籤鏈結,爬取當前標籤下全部頁面page_list

然後我們的爬蟲**裡面有4層,層與層之間通過meta引數傳遞資料,例如parse到parse_page時,資料傳遞是yield scrapy.request(url=item[『tag_href』], meta=, callback=self.parse_page),其他各層傳遞與這個一樣,到最後一層的時候就yield item,供pipeline使用。

爬蟲**整個**如下:

import scrapy

from meizitu.items import meizituitem

class mztspider(scrapy.spider):

name = 『mzt』

allowed_domains = [『meizitu.com』]

start_urls = [『

def parse(self, response):

"""提取標籤名稱和鏈結

:param response:

:return:

"""tags = response.xpath(".//*[@class='tags']/span/a")

for i in tags:

item = meizituitem()

tag_href = i.xpath(".//@href").extract()[0]

tag_name = i.xpath(".//@title").extract()[0]

item['tag_name'] = tag_name

item['tag_href'] = tag_href

yield scrapy.request(url=item['tag_href'], meta=, callback=self.parse_page)

def parse_page(self, response):

"""提取標籤下鏈結

:param response:

:return:

"""# 進入某個標籤後,爬取底部分頁按鈕

page_lists = response.xpath(".//*[@id='wp_page_numbers']/ul/li")

# 獲取底部分頁按鈕上的文字,根據文本來判斷當前標籤頁下總共有多少分頁

page_list = page_lists.xpath('.//text()')

# 如果當前標籤頁下有多個頁面,則再根據第乙個按鈕是否為「首頁」來進行再次提取,因為這裡有的頁面第乙個按鈕是「首頁」,有的第乙個按鈕是「1」

if len(page_lists) > 0:

if page_list[0].extract() == '首頁':

page_num = len(page_lists) - 3

else:

page_num = len(page_lists) - 2

else:

page_num = 1

# 根據當前標籤頁的鏈結,來拼成帶頁碼的鏈結

if '_' in response.url:

index = response.url[::-1].index('_')

href_pre = response.url[:-index]

else:

if page_num == 1:

href_pre = response.url.split('.html')[0]

else:

href_pre = response.url.split('.html')[0] + '_'

for i in range(1, page_num + 1):

if page_num == 1:

href = href_pre + '.html'

else:

href = href_pre + str(i) + '.html'

item = response.meta['item']

item['page_list'] = href

yield scrapy.request(url=item['page_list'], meta=, callback=self.parse_album)

def parse_album(self, response):

"""提取**名稱和**鏈結

:param response:

:return:

"""albums = response.xpath(".//*[@class='pic']")

for album in albums:

album_href = album.xpath(".//a/@href").extract()[0]

album_name = album.xpath(".//a/img/@alt").extract()[0]

item = response.meta['item']

item['album_name'] = album_name

item['album_href'] = album_href

yield scrapy.request(url=item['album_href'], meta=, callback=self.parse_img)

def parse_img(self, response):

""":param response:

:return:

"""img_list = response.xpath(".//p/img")

for img in img_list:

item = response.meta['item']

img_title = img.xpath(".//@alt").extract()[0]

if img_title == '':

for i in range(1, len(img_list) + 1):

img_title = item['album_name'] + '_' + str(i)

else:

img_title = img_title

img_urls = img.xpath(".//@src").extract()

img_src = img.xpath(".//@src").extract()[0]

item['img_title'] = img_title

item['img_src'] = img_src

item['img_urls'] = img_urls

yield item

然後坑的地方就出現了,按照理想狀態,最後的item資料每個都是唯一的,但是實際情況是最後的item很多資料都是重複和錯亂的,要麼只取了最後一張,要麼和**對不上,完全不對。

後來在網上查了很久,終於找到這篇文章,作者的文章中說:

查詢原因後,發現是因為使用 request 函式傳遞 item 時,使用的是淺複製(物件的字段值被複製時,字段引用的物件不會被複製)

Scrapy中的item是什麼

這兩天看scrapy,看到item這個東西,覺得有點抽象,查了一下,有點明白了。item 是儲存爬取到的資料的容器 其使用方法和python字典類似,並且提供了額外保護機制來避免拼寫錯誤導致的未定義字段錯誤。爬取的主要目標就是從非結構性的資料來源提取結構性資料,例如網頁。scrapy提供 item ...

Scrapy中的item是什麼

這兩天看scrapy,看到item這個東西,覺得有點抽象,查了一下,有點明白了。item 是儲存爬取到的資料的容器 其使用方法和python字典類似,並且提供了額外保護機制來避免拼寫錯誤導致的未定義字段錯誤。爬取的主要目標就是從非結構性的資料來源提取結構性資料,例如網頁。scrapy提供 item ...

Scrapy中的Item與ItemLoader物件

scrapy之item與itemload item物件是種簡單的容器,類似於python的字典,用於儲存處理爬取到的內容,item的用法與字典基本一致,所以可以把item當做字典來操作 item宣告在scrapy專案的items.py中,通過class和field物件來宣告 import scrap...