请问用 scrapy 框架写爬虫时,应该如何关闭数据库游标和数据库连接才安全?

2017-10-11 20:00:39 +08:00
 saximi
用 scrapy 框架中的 Spider 模版来写爬虫,爬网页过程中将数据插入到数据库里,为了能在正常结束和异常中断的情况下都能关闭数据库游标和数据库连接,我在 start_requests 方法中用了 try 和 finally 语句,在 try 中返回 Request 对象,在 finally 中关闭游标和数据库连接。程序的大致结构如下,其中一些操作用汉字来描述了。

实际运行时,执行到 parse()中的将 item 值插入数据库时报错,提示游标未打开。
发现是因为在执行 yield Request()语句时,会先运行 finally 中的语句,然后才执行 parse()方法,从而使得游标在 finally 中先被关闭,进而报错。

恳请大家指点,大家在用 Spider 模板写爬虫时,为了确保在正常和异常状态下都能关闭游标和数据库连接,这些关闭的操作都是放在哪里实现的呢?
感谢!

class MySpider(Spider):

	连接数据库的语句
	打开游标的语句

	def start_requests(self):
		driver.get(url)
		try:
			yield Request(url=url, callback=self.parse) 
		finally:
			关闭游标的语句
			关闭数据库连接的语句

	def parse(self, response):
		解析页面元素并赋值给 item 字典对象
		将 item 的值插入到数据库中
                yield item
3054 次点击
所在节点    Python
9 条回复
sunchen
2017-10-11 20:21:52 +08:00
pipeline 实现 close_spider 方法
sunchen
2017-10-11 20:23:05 +08:00
写库过程写到 pipeline 里, pipeline 实现 close_spider 方法
Lax
2017-10-11 20:27:42 +08:00
别的语言异常处理都是用 catch
anguslg
2017-10-12 10:48:13 +08:00
吐槽一下楼主的 md 排版 问题描述至少换个行吧,别人看起来也方便
saximi
2017-10-12 20:44:46 +08:00
@sunchen 谢谢指点,关于这个做法,我有疑问。例如下面这三个方法返回的对象,如果在爬虫主程序中和 pipelines.py 中都要访问,要如何才能在两个文件之间正确传递呢?
pymysql.connect()
pymysql.connect().cursor()
webdriver.Chrome()
saximi
2017-10-12 20:45:29 +08:00
@sunchen 因为 pipelines.pymiddlewares.py 中都可以定义这两个方法:open_spider()、close_spider()。
那么如果两个文件中同名方法的处理逻辑出现冲突了怎么办呢?
saximi
2017-10-12 20:47:05 +08:00
@anguslg 呵呵,真不好意思,我的主贴中虽然把问题描述分为了三个段落,但是每行内容确实很长,下回我会注意让每行内容不要太长的。
sunchen
2017-10-13 14:19:09 +08:00
@saximi 建议分开,如果因为某些原因必须同时持有同一个 connection 对象的话,用 spider 对象持有,pipeline 和 middleware 都已访问到,pipelines 和 middleware 中的方法不会冲突的
saximi
2017-10-13 23:34:53 +08:00
@sunchen 您说的 spider 对象就是 pipeline 中的 self 对象吧?
如果不是的话,能否举例告知 spider 对象中的什么属性可以存放上述三个方法返回的对象呢?

关于不同文件中同名方法的冲突,我担心的是 pipelines.pymiddlewares.py 中都有这两个方法时:open_spider()、close_spider(),比如开发人员一时粗心,在 pipelines.py 的 open 方法中将某个变量赋 A 值,但是在 middlewares.py 中的 open 方法中又将整个变量赋 B 值,此时就会出现冲突了,到底实际运行起来,会以哪个文件中的方法为准呢?

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/396891

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX