Python でいくつかのリンクとメタ タグを選択するために、scrapy フレームワークを使用してクローラーを作成しました。次に、開始 URL をクロールし、データを JSON エンコード形式でファイルに書き込みます。問題は、クローラーが 2 回または 3 回実行される場合です。同じ開始 URL を使用すると、ファイル内のデータが重複します。これを回避するために、スクレイピーでダウンローダー ミドルウェアを使用しました。
私がしたことは、上記のコードをスクレイピー プロジェクト内のファイルにコピー アンド ペーストし、次の行を追加して settings.py ファイルで有効にしたことです。
SPIDER_MIDDLEWARES = {'a11ypi.removeDuplicates.IgnoreVisitedItems':560}
ここで、「a11ypi.removeDuplicates.IgnoreVisitedItems」はクラスパス名です。最後に、items.py ファイルに移動して変更し、次のフィールドを含めました。
visit_id = Field()
visit_status = Field()
しかし、これは機能せず、クローラーは同じ結果を生成し、2 回実行するとファイルに追加します。
次のように、pipelines.py ファイル内のファイルへの書き込みを行いました。
import json
class AYpiPipeline(object):
def __init__(self):
self.file = open("a11ypi_dict.json","ab+")
# this method is called to process an item after it has been scraped.
def process_item(self, item, spider):
d = {}
i = 0
# Here we are iterating over the scraped items and creating a dictionary of dictionaries.
try:
while i<len(item["foruri"]):
d.setdefault(item["foruri"][i],{}).setdefault(item["rec"][i],{})[item["foruri_id"][i]] = item['thisurl'] + ":" +item["thisid"][i]
i+=1
except IndexError:
print "Index out of range"
json.dump(d,self.file)
return item
私のスパイダーコードは次のとおりです。
from scrapy.contrib.spiders import CrawlSpider, Rule
from scrapy.contrib.linkextractors.sgml import SgmlLinkExtractor
from scrapy.selector import HtmlXPathSelector
from a11ypi.items import AYpiItem
class AYpiSpider(CrawlSpider):
name = "a11y.in"
allowed_domains = ["a11y.in"]
# This is the list of seed URLs to begin crawling with.
start_urls = ["http://www.a11y.in/a11ypi/idea/fire-hi.html"]
# This is the callback method, which is used for scraping specific data
def parse(self,response):
temp = []
hxs = HtmlXPathSelector(response)
item = AYpiItem()
wholeforuri = hxs.select("//@foruri").extract() # XPath to extract the foruri, which contains both the URL and id in foruri
for i in wholeforuri:
temp.append(i.rpartition(":"))
item["foruri"] = [i[0] for i in temp] # This contains the URL in foruri
item["foruri_id"] = [i.split(":")[-1] for i in wholeforuri] # This contains the id in foruri
item['thisurl'] = response.url
item["thisid"] = hxs.select("//@foruri/../@id").extract()
item["rec"] = hxs.select("//@foruri/../@rec").extract()
return item
何をすべきかを親切に提案してください。