我正在尝试以下操作:
1.从一些页面中抓取一些项目(包括URL)。
1.保存每个项目到一个mysql数据库
1.获取先前添加的记录的(auto_increment)ID
1.抓取上述URL指向的页面(#1)
1.保存此页上的所有项目,并引用(外键)到#3中定义的ID
在我看来,这是一个非常常见的问题,应该有一个相当简单的解决方案。
“item_scraped”信号看起来像是一个显而易见的解决方案,因为它提供了一个回调函数,用于在项目被完全处理时进行回调。
但是,似乎不可能从回调中启动另一个请求。
我在这里读到一些人建议使用Spider中间件,但我不知道如何使用,特别是因为Spider中间件本身不应该启动请求。
我在Python 3.8上使用的是Scrapy 2.6.2。
谢谢你的帮助。
下面是我的简化代码,没有错误处理等。
蜘蛛
import scrapy
from scrapy import signals
class MySpider(scrapy.Spider):
name = 'MySpider'
allowed_domains = ['www.somedomain.com']
start_urls = [
'https://www.somedomain.com/someurl/',
]
@classmethod
def from_crawler(cls, crawler, *args,**kwargs):
spider = cls()
# requests the callback once an item is scraped
crawler.signals.connect(spider.item_scraped, signals.item_scraped)
return spider
def parse(self, response):
for node in response.xpath(".//tr/td[@class='foo']"):
yield {
'a': ...
'b': ...
'url': ...
}
def item_scraped(self, item, response, spider):
###
### UNFORTUNATELY THIS IS NOT POSSIBLE
###
# forwards the new ID as a meta variable
yield Request(item['url'], meta={'id':item['id']}, callback=self.parse_page)
def parse_page(self, response):
for node in response.xpath("//div[@class='soemthing']//a"):
yield {
'id': response.meta['id'],
'title': ...
}
和管道:
import mysql.connector
class WinebotPipeline(object):
def __init__(self):
self.conf = {'host': ..., 'user': ..., 'password': ..., 'database': ...}
self.connection = self.mysql_connect()
self.cursor = self.connection.cursor()
def mysql_connect(self):
return mysql.connector.connect(**self.conf)
def process_item(self, item, spider):
sql = "insert into `some_table` (`a`, `b`, `url`) values (%s, %s, %s)"
self.cursor.execute(sql, list(item.values()))
self.connection.commit()
# id of last inserted item
item['id'] = self.cursor.lastrowid
return item
1条答案
按热度按时间jfgube3f1#
一个更简单的方法是从第一个页面获取所有的信息,然后使用url生成一个新的请求,用
parse_page
方法作为回调函数,用scraped数据作为回调函数kwargs,然后从第二个url中获取必要的信息,然后将其添加到第一个页面的结果中,生成完整的条目。然后,您可以一次完成所有数据库条目。蜘蛛
管道