在 C 中使用 scrapy 嵌入 Python 时出现段错误
Segfault while embedding Python using scrapy in C
我目前正尝试从 C 代码 运行 一些 scrapy spider(在 Python 中),但我在测试时不断遇到段错误。
我有这段代码可以让我 运行 来自 c 的简单 python 函数 :
int main() {
PyObject *retour, *module, *fonction, *arguments;
char *resultat;
Py_Initialize();
PySys_SetPath(".");
module = PyImport_ImportModule("test");
fonction = PyObject_GetAttrString(module, "hellowrld);
arguments = Py_BuildValue("(s)", "hello world");
retour = PyEval_CallObject(fonction, arguments);
PyArg_Parse(retour, "s", &resultat);
printf("Resultat: %s\n", resultat);
Py_Finalize();
return 0;
}
如果我在 test.py
中调用看起来像这样的 hellowrld 函数
def hellowrld(arg):
return arg + '!!'
它会工作正常,但我正在尝试 运行 函数 runspider_with_url 从这段代码:
# -*- coding: utf-8 -*-
import scrapy
from scrapy.crawler import CrawlerProcess
import lxml.etree
import lxml.html
class GetHtmlSpider(scrapy.Spider):
name = "getHtml"
def __init__(self, var_url=None, *args, **kwargs):
super(GetHtmlSpider, self).__init__(*args, **kwargs)
self.start_urls = [var_url]
def parse(self,response):
root = lxml.html.fromstring(response.body)
print lxml.html.tostring(root)
def runspider_with_url(var_url):
process = CrawlerProcess({
'USER_AGENT': 'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)'
})
process.crawl(GetHtmlSpider,var_url=var_url)
process.start()
return "It works!!"
当我尝试执行它时,我不断收到分段错误
我试图在 python
的末尾添加这个
foo = runspider_with_url("http://www.google.com/")
print foo
当我在 bash 中使用以下命令执行此调用时,此调用有效:
python -c 'import get_html; get_html.runspider_with_url("https://www.wikipedia.org")'
所以我可以让我的 C 程序用 bash 执行 python,并将结果写入 .txt,但我不想这样做。
谢谢
PyArg_Parse(retour, "s", &resultat);
处存在段错误,因为脚本引发异常并且 retour
为 NULL。在一些错误检测中包装后,问题是 PySys_SetPath(".");
替换了现有的 sys.path
,因此无法再导入 scrapy
之类的东西。因此,我通过快速调用插入 sys.path
的 python 代码来修复该问题。在此过程中添加额外的错误处理,你得到
#include <stdio.h>
#include <stdlib.h>
#include <Python.h>
int main() {
PyObject *retour, *module, *fonction, *arguments;
char *resultat;
printf("starting\n");
Py_Initialize();
//PySys_SetPath(".");
if(PyRun_SimpleString("import sys;sys.path.insert(0, '.')"))
{
printf("path expansion failed\n");
return(2);
}
module = PyImport_ImportModule("test");
if(module == NULL) {
printf("import failed\n");
PyErr_Print();
return(2);
}
fonction = PyObject_GetAttrString(module, "runspider_with_url");
if(fonction == NULL) {
printf("could not find function\n");
return(2);
}
arguments = Py_BuildValue("(s)", "hello world");
if(arguments == NULL) {
printf("arg parsing failed\n");
return(2);
}
printf("Calling\n");
retour = PyEval_CallObject(fonction, arguments);
printf("Returned\n");
// note: need to release arguments
Py_DECREF(arguments);
if(retour == NULL) {
printf("It all went wrong\n");
PyErr_Print();
return(2);
}
PyArg_Parse(retour, "s", &resultat);
printf("Resultat: %s\n", resultat);
Py_Finalize();
return 0;
}
我目前正尝试从 C 代码 运行 一些 scrapy spider(在 Python 中),但我在测试时不断遇到段错误。
我有这段代码可以让我 运行 来自 c 的简单 python 函数 :
int main() {
PyObject *retour, *module, *fonction, *arguments;
char *resultat;
Py_Initialize();
PySys_SetPath(".");
module = PyImport_ImportModule("test");
fonction = PyObject_GetAttrString(module, "hellowrld);
arguments = Py_BuildValue("(s)", "hello world");
retour = PyEval_CallObject(fonction, arguments);
PyArg_Parse(retour, "s", &resultat);
printf("Resultat: %s\n", resultat);
Py_Finalize();
return 0;
}
如果我在 test.py
中调用看起来像这样的 hellowrld 函数def hellowrld(arg):
return arg + '!!'
它会工作正常,但我正在尝试 运行 函数 runspider_with_url 从这段代码:
# -*- coding: utf-8 -*-
import scrapy
from scrapy.crawler import CrawlerProcess
import lxml.etree
import lxml.html
class GetHtmlSpider(scrapy.Spider):
name = "getHtml"
def __init__(self, var_url=None, *args, **kwargs):
super(GetHtmlSpider, self).__init__(*args, **kwargs)
self.start_urls = [var_url]
def parse(self,response):
root = lxml.html.fromstring(response.body)
print lxml.html.tostring(root)
def runspider_with_url(var_url):
process = CrawlerProcess({
'USER_AGENT': 'Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)'
})
process.crawl(GetHtmlSpider,var_url=var_url)
process.start()
return "It works!!"
当我尝试执行它时,我不断收到分段错误
我试图在 python
的末尾添加这个foo = runspider_with_url("http://www.google.com/")
print foo
当我在 bash 中使用以下命令执行此调用时,此调用有效:
python -c 'import get_html; get_html.runspider_with_url("https://www.wikipedia.org")'
所以我可以让我的 C 程序用 bash 执行 python,并将结果写入 .txt,但我不想这样做。
谢谢
PyArg_Parse(retour, "s", &resultat);
处存在段错误,因为脚本引发异常并且 retour
为 NULL。在一些错误检测中包装后,问题是 PySys_SetPath(".");
替换了现有的 sys.path
,因此无法再导入 scrapy
之类的东西。因此,我通过快速调用插入 sys.path
的 python 代码来修复该问题。在此过程中添加额外的错误处理,你得到
#include <stdio.h>
#include <stdlib.h>
#include <Python.h>
int main() {
PyObject *retour, *module, *fonction, *arguments;
char *resultat;
printf("starting\n");
Py_Initialize();
//PySys_SetPath(".");
if(PyRun_SimpleString("import sys;sys.path.insert(0, '.')"))
{
printf("path expansion failed\n");
return(2);
}
module = PyImport_ImportModule("test");
if(module == NULL) {
printf("import failed\n");
PyErr_Print();
return(2);
}
fonction = PyObject_GetAttrString(module, "runspider_with_url");
if(fonction == NULL) {
printf("could not find function\n");
return(2);
}
arguments = Py_BuildValue("(s)", "hello world");
if(arguments == NULL) {
printf("arg parsing failed\n");
return(2);
}
printf("Calling\n");
retour = PyEval_CallObject(fonction, arguments);
printf("Returned\n");
// note: need to release arguments
Py_DECREF(arguments);
if(retour == NULL) {
printf("It all went wrong\n");
PyErr_Print();
return(2);
}
PyArg_Parse(retour, "s", &resultat);
printf("Resultat: %s\n", resultat);
Py_Finalize();
return 0;
}