admin 管理员组文章数量: 1086019
scarpy框架如何在crawl中正确传递自定义参数,scrapy.cmdline的execute为什么不能在while True中无限循环,execute换成crawl 方法
问题:scrapy.cmdline的execute函数执行完毕为什么一定会停,不能执行后面函数,也不在while True中无限循环(解决问题的结果 在最后)
我想让scrapy程序全年无休止运行,24小时后重新再次运行
from scrapy.cmdline import execute
# execute(["scrapy","crawl",'End_Allcity',"-a","city=[\"福建省\"]"])
def run1(city1=str(-1)):#上execute(["scrapy","crawl",'AllProvinceTestNew',"-a","num={}".format(city1)])print("*" * 100 + f"一轮抓取完成{datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')}" + "*" * 100)time.sleep(60 * 60 *24)
if __name__== '__main__':# run1()while True:process = multiprocessing.Process(target=run1())process.start()process.join()
该函数无法在while True中无限循环,全自动运行
class ZizhiSpider(scrapy.Spider):def __init__(self, num):super().__init__()self.spider_num = int(num)# print("开始爬取{}".format(self.spider_num))
原因分析
在 Scrapy 中,scrapy.cmdline.execute() 函数用于执行命令行命令,例如 scrapy crawl。这个函数是 Scrapy 的一个阻塞函数,也就是说它会一直等待命令执行完成后才会返回。因此,在 scrapy.cmdline.execute() 执行完毕后,后面的代码才会被执行。
如果你想要在 Scrapy 命令执行完成后继续执行其他函数,可以将这些函数放在回调函数中,并在 Scrapy 命令执行完成时调用这些回调函数。例如:
from scrapy import cmdline, signals
from scrapy.signalmanager import dispatcherdef main():cmdline.execute(['scrapy', 'crawl', 'myspider'])def my_callback():print("Scrapy 命令执行完成!")# 在这里执行其他函数if __name__ == '__main__':# 注册回调函数dispatcher.connect(my_callback, signal=signals.spider_closed)# 执行 Scrapy 命令main()
在这个示例中,我们使用 signals.spider_closed 信号来注册一个回调函数 my_callback。当 Scrapy 命令执行完成后,signals.spider_closed 信号会被触发,从而调用回调函数 my_callback。在 my_callback 函数中,你可以执行其他代码或函数。
值得注意的是,由于 scrapy.cmdline.execute() 函数是阻塞的,因此你不能将它放在一个无限循环中执行。如果你需要在 Scrapy 命令执行完成后继续执行其他函数,可以使用上述的回调函数方式。
阻塞函数的定义(要看解决问题的结果跳过改章节段)
scrapy.cmdline的execute阻塞函数类似于subprocess 模块中的 subprocess.run() 或 subprocess.Popen()
在 Python 中,execute 函数通常是指 subprocess 模块中的 subprocess.run() 或 subprocess.Popen() 函数,用于执行一个外部命令并等待其完成。
当 subprocess.run() 或 subprocess.Popen() 执行完成后,程序会停止因为主程序的执行已经结束。如果你想要在执行完成后保持程序继续运行,可以使用 subprocess.Popen() 函数,并在调用它时指定 shell=True 参数。这样的话,子进程将在新的 shell 中运行,而父进程将不会与之关联,从而使程序可以继续运行。
可以使用如下代码来在 Python 中执行一个长时间运行的 shell 命令,并在执行完成后保持程序继续运行:
import subprocess# 在 Windows 上执行 ping 命令
p = subprocess.Popen("ping -t 127.0.0.1", shell=True)# 在 Linux 或 macOS 上执行 ping 命令
# p = subprocess.Popen("ping 127.0.0.1", shell=True)# 程序继续运行
print("Ping 命令已启动")# 等待用户按下 Ctrl + C 终止程序
try:while True:pass
except KeyboardInterrupt:# 用户按下 Ctrl + C,终止程序p.terminate()print("Ping 命令已停止")
在这个示例中,我们使用 subprocess.Popen() 函数来启动一个长时间运行的 ping 命令,并使用 shell=True 参数来启动一个新的 shell 来运行这个命令。然后程序可以继续运行,直到用户按下 Ctrl + C 终止程序。注意,我们使用了 p.terminate() 来终止子进程的运行,以防止它一直在后台运行。
subprocess.run()和subprocess.Popen() 是阻塞函数吗?
ChatGPT
subprocess.run() 和 subprocess.Popen() 函数都可以执行外部命令,但它们的运行方式有所不同。
subprocess.run() 函数是 Python 3.5 开始引入的一个快捷函数,用于执行外部命令并等待它完成。这个函数是一个阻塞函数,也就是说它会一直等待子进程完成后才会返回。因此,subprocess.run() 函数会阻塞主程序的执行,直到子进程执行完成后才会继续执行主程序。例如:
import subprocessresult = subprocess.run(['ls', '-l'], stdout=subprocess.PIPE)
print(result.stdout.decode())
在这个示例中,subprocess.run() 函数用于执行 ls -l 命令,并等待它完成后打印命令的输出。subprocess.run() 函数会一直阻塞程序的执行,直到子进程执行完成后才会返回 result 对象。
相比之下,subprocess.Popen() 函数是一个非阻塞函数,也就是说它会创建一个子进程来执行外部命令,但不会阻塞主程序的执行。这个函数会立即返回一个 Popen 对象,通过这个对象我们可以控制子进程的运行。例如:
import subprocessprocess = subprocess.Popen(['ls', '-l'], stdout=subprocess.PIPE)
out, err = processmunicate()
print(out.decode())
在这个示例中,subprocess.Popen() 函数用于启动一个 ls -l 命令,并返回一个 Popen 对象。然后我们使用 communicate() 方法等待子进程完成,并获取命令的输出。注意到我们在调用 communicate() 方法时并没有阻塞主程序的执行,所以程序可以继续执行后面的代码。
综上所述,subprocess.run() 函数是一个阻塞函数,而 subprocess.Popen() 函数是一个非阻塞函数。因此无法在while True中无限循环,全自动运行程序。
解决问题的原理 execute换成crawl 方法
在scarpy框架中,下面代码如何用process = CrawlerProcess(get_project_settings()) process.crawl(spidername) process.start()改写execute([“scrapy”,“crawl”,‘AllProvinceTestNew’,“-a”,“num={}”.format(city1)]),如何在crawl中加参数
ChatGPT
在 Scrapy 框架中,通过 CrawlerProcess 来启动一个爬虫进程,并使用 crawl 方法来指定要运行的 Spider。如果你需要将参数传递给 Spider,可以通过在 crawl 方法中使用 settings 参数来传递。
下面是一个示例代码:
from scrapy.crawler import CrawlerProcess
from scrapy.utils.project import get_project_settingsprocess = CrawlerProcess(get_project_settings())
process.crawl(spidername, city=city1)
process.start()
在这个例子中,我们需要将 city1 参数传递给 Spider。我们在 crawl 方法中使用 city=city1 来指定这个参数,并将其作为一个关键字参数传递。
在 Spider 中,你可以通过接收 city 参数来使用这个参数。例如,你可以在 Spider 的构造函数中添加一个参数并保存它,以便在 Spider 的其他方法中使用:
class MySpider(scrapy.Spider):name = "myspider"def __init__(self, city=None, *args, **kwargs):super(MySpider, self).__init__(*args, **kwargs)self.city = citydef start_requests(self):url = "/{}".format(self.city)yield scrapy.Request(url=url, callback=self.parse)def parse(self, response):# do something with the responsepass
在这个例子中,我们添加了一个名为 city 的参数,将其保存为 Spider 的一个属性,然后在 start_requests 方法中使用它来构造请求 URL。你可以在其他方法中使用这个属性来执行其他操作。
解决问题的结果 execute换成crawl 方法,可以在while True中无限循环
import multiprocessingfrom scrapy.cmdline import execute
# execute(["scrapy","crawl",'End_Allcity',"-a","city=[\"福建省\"]"])
def run1(city1=str(-1)):#上print(city1)process = CrawlerProcess(settings=get_project_settings())process.crawl("AllProvinceTestNew",city1)process.start()# execute(["scrapy","crawl",'AllProvinceTestNew',"-a","num={}".format(city1)])print("*" * 100 + f"一轮抓取完成{datetime.datetime.now().strftime('%Y-%m-%d %H:%M:%S')}" + "*" * 100)time.sleep(60 * 60 *24)if __name__== '__main__':# run1()while True:process = multiprocessing.Process(target=run1())process.start()process.join()
本文标签: scarpy框架如何在crawl中正确传递自定义参数,scrapycmdline的execute为什么不能在while True中无限循环,execute换成crawl 方法
版权声明:本文标题:scarpy框架如何在crawl中正确传递自定义参数,scrapy.cmdline的execute为什么不能在while True中无限循环,execute换成crawl 方法 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.roclinux.cn/b/1693408921a220234.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论