Ich habe versucht, this pipeline in meinem Spider zu implementieren. Nach der Installation der notwendigen Abhängigkeiten kann ich die Spinne ohne Fehler ausführen, aber aus irgendeinem Grund schreibt es nicht in meine Datenbank.Pipeline schreibt nicht nach MySQL, aber gibt auch keinen Fehler
Ich bin mir ziemlich sicher, dass mit der Verbindung zur Datenbank etwas nicht in Ordnung ist. Wenn ich ein falsches Passwort eingib, bekomme ich immer noch keinen Fehler.
Wenn die Spinne alle Daten abgekratzt hat, braucht sie ein paar Minuten, bevor sie mit dem Speichern der Statistiken beginnt.
2017-08-31 13:17:12 [scrapy] INFO: Closing spider (finished)
2017-08-31 13:17:12 [scrapy] INFO: Stored csv feed (27 items) in: test.csv
2017-08-31 13:24:46 [scrapy] INFO: Dumping Scrapy stats:
Pipeline:
import MySQLdb.cursors
from twisted.enterprise import adbapi
from scrapy.xlib.pydispatch import dispatcher
from scrapy import signals
from scrapy.utils.project import get_project_settings
from scrapy import log
SETTINGS = {}
SETTINGS['DB_HOST'] = 'mysql.domain.com'
SETTINGS['DB_USER'] = 'username'
SETTINGS['DB_PASSWD'] = 'password'
SETTINGS['DB_PORT'] = 3306
SETTINGS['DB_DB'] = 'database_name'
class MySQLPipeline(object):
@classmethod
def from_crawler(cls, crawler):
return cls(crawler.stats)
def __init__(self, stats):
print "init"
#Instantiate DB
self.dbpool = adbapi.ConnectionPool ('MySQLdb',
host=SETTINGS['DB_HOST'],
user=SETTINGS['DB_USER'],
passwd=SETTINGS['DB_PASSWD'],
port=SETTINGS['DB_PORT'],
db=SETTINGS['DB_DB'],
charset='utf8',
use_unicode = True,
cursorclass=MySQLdb.cursors.DictCursor
)
self.stats = stats
dispatcher.connect(self.spider_closed, signals.spider_closed)
def spider_closed(self, spider):
print "close"
""" Cleanup function, called after crawing has finished to close open
objects.
Close ConnectionPool. """
self.dbpool.close()
def process_item(self, item, spider):
print "process"
query = self.dbpool.runInteraction(self._insert_record, item)
query.addErrback(self._handle_error)
return item
def _insert_record(self, tx, item):
print "insert"
result = tx.execute(
" INSERT INTO matches(type,home,away,home_score,away_score) VALUES (soccer,"+item["home"]+","+item["away"]+","+item["score"].explode("-")[0]+","+item["score"].explode("-")[1]+")"
)
if result > 0:
self.stats.inc_value('database/items_added')
def _handle_error(self, e):
print "error"
log.err(e)
Spider:
import scrapy
import dateparser
from crawling.items import KNVBItem
class KNVBspider(scrapy.Spider):
name = "knvb"
start_urls = [
'http://www.knvb.nl/competities/eredivisie/uitslagen',
]
custom_settings = {
'ITEM_PIPELINES': {
'crawling.pipelines.MySQLPipeline': 301,
}
}
def parse(self, response):
# www.knvb.nl/competities/eredivisie/uitslagen
for row in response.xpath('//div[@class="table"]'):
for div in row.xpath('./div[@class="row"]'):
match = KNVBItem()
match['home'] = div.xpath('./div[@class="value home"]/div[@class="team"]/text()').extract_first()
match['away'] = div.xpath('./div[@class="value away"]/div[@class="team"]/text()').extract_first()
match['score'] = div.xpath('./div[@class="value center"]/text()').extract_first()
match['date'] = dateparser.parse(div.xpath('./preceding-sibling::div[@class="header"]/span/span/text()').extract_first(), languages=['nl']).strftime("%d-%m-%Y")
yield match
Wenn es besser sind Rohrleitungen zur Verfügung zu tun, was ich versuche das auch willkommen zu erreichen sein würde. Vielen Dank!
Update: Mit dem Link in der akzeptierte Antwort vorausgesetzt ich schließlich auf diese Funktion habe, die funktioniert (und gelöst damit mein Problem):
def process_item(self, item, spider):
print "process"
query = self.dbpool.runInteraction(self._insert_record, item)
query.addErrback(self._handle_error)
query.addBoth(lambda _: item)
return query
Ihre Einrückung scheint falsch zu sein. '_insert_error' und' _handle_error' sind nicht Teil der Pipeline. Hast du überprüft, ob 'process_item' in deiner Pipeline aufgerufen wird (etwas ausgedruckt)? –
Aktualisierte den Code mit einigen Drucken und fester Einrückung. 'process_item' wird aufgerufen, sowie alle anderen Funktionen außer' _insert_record' und '_handle_error'. Ich bin wirklich erstaunt, dass es so weit kommt, während die Verbindung in der 'init'-Funktion mit einem falschen Passwort fehlschlagen sollte, aber aus irgendeinem Grund bekomme ich keinen Fehler dafür. – Casper
@Casper Haben Sie Zugriff auf MySQL-Serverprotokolle? Wenn ja, versuchen Sie es zu überprüfen, Sie könnten etwas finden. –