Использование Middleware для игнорирования дубликатов в Scrapy
Я новичок в Python, и я использую Scrapy для кадрового веб-проекта.
Я использую Scrapy для многократного извлечения данных с нескольких веб-сайтов, поэтому мне нужно при каждом сканировании проверять, есть ли ссылка в базе данных, прежде чем добавить ее. Я сделал это в классе piplines.py:
class DuplicatesPipline(object):
def process_item(self, item, spider):
if memc2.get(item['link']) is None:
return item
else:
raise DropItem('Duplication %s', item['link'])
Но я слышал, что для этой задачи лучше использовать Middleware.
Мне было немного сложно использовать Middleware в Scrapy, может кто-нибудь перенаправить меня к хорошему учебнику.
Советы приветствуются.
Спасибо,
Редактировать:
Я использую MySql и memcache.
Вот моя попытка в соответствии с ответом @Talvalin:
# -*- coding: utf-8 -*-
from scrapy.exceptions import IgnoreRequest
import MySQLdb as mdb
import memcache
connexion = mdb.connect('localhost','dev','passe','mydb')
memc2 = memcache.Client(['127.0.0.1:11211'], debug=1)
class IgnoreDuplicates():
def __init__(self):
#clear memcache object
memc2.flush_all()
#update memc2
with connexion:
cur = connexion.cursor()
cur.execute('SELECT link, title FROM items')
for item in cur.fetchall():
memc2.set(item[0], item[1])
def precess_request(self, request, spider):
#if the url is not in memc2 keys, it returns None.
if memc2.get(request.url) is None:
return None
else:
raise IgnoreRequest()
DOWNLOADER_MIDDLEWARES = {
'myproject.middlewares.IgnoreDuplicates': 543,
'scrapy.contrib.downloadermiddleware.httpproxy.HttpProxyMiddleware': 500, }
Но похоже, что метод process_request игнорируется при сканировании.
Заранее спасибо,
1 ответ
Вот пример кода промежуточного программного обеспечения, который загружает URL-адреса из таблицы sqlite3 (Id INT, url TEXT)
в набор, а затем проверяет URL запроса относительно набора, чтобы определить, следует ли игнорировать URL или нет. Было бы достаточно просто адаптировать этот код для использования MySQL и memcache, но, пожалуйста, дайте мне знать, если у вас есть какие-либо проблемы или вопросы.:)
import sqlite3
from scrapy.exceptions import IgnoreRequest
class IgnoreDuplicates():
def __init__(self):
self.crawled_urls = set()
with sqlite3.connect('C:\dev\scrapy.db') as conn:
cur = conn.cursor()
cur.execute("""SELECT url FROM CrawledURLs""")
self.crawled_urls.update(x[0] for x in cur.fetchall())
print self.crawled_urls
def process_request(self, request, spider):
if request.url in self.crawled_urls:
raise IgnoreRequest()
else:
return None
На случай, если у вас возникнут проблемы с импортом, такие как я, и вы собираетесь пробить монитор, приведенный выше код был в middlewares.py
файл, который был помещен в папку проекта верхнего уровня со следующим DOWNLOADER_MIDDLEWARES
установка
DOWNLOADER_MIDDLEWARES = {
'myproject.middlewares.IgnoreDuplicates': 543,
'scrapy.contrib.downloadermiddleware.httpproxy.HttpProxyMiddleware': 500,
}