有没有老哥介绍工作会用c/#调用python脚本的

下次自动登录
现在的位置:
& 综合 & 正文
用脚本C调用Python脚本文件里的函数
像因特网的Web系统一样, 几乎所有的大规模软件系统, 都会使用脚本语言. 在网络游戏服务器的开发中, 也会应用脚本语言. 游戏开发常用的脚本语言主要有: Python, Lua. 本文介绍在C语言中嵌入Python支持, C语言和Python语言通过API进行交互.
任何两种语言要整合, 首先要解决通信问题. C要和Python进行通信, 要进行数据结构转换, 把C的数据结构转为Python的对象, 和把Python对象转换为C数据结构.
下面对代码实例进行讲解, 代码忽略和错误处理.
#include &python2.5/Python.h&
void test1();
void test2();
PyObject *globals
int main(int argc, char **argv){
PyObject *m, *obj1, *
PyObject *request, *
Py_Initialize();
变量声明, 以及调用初始化函数 Py_Initialize().
m = PyImport_AddModule("__main__");
globals = PyModule_GetDict(m);
获取全局变量的字典表(哈希表). 在 Python 脚本中, 该字典表的键名就是全局变量的的名字. 例如, 全局变量字典表中有一项记录 ‘a’ =& ‘123′, 那么, 在 Python 脚本中, 变量 a 的值是 ‘123′. 该字典表就是 C 语言和 Python 语言进行通信的关键.
request = PyDict_New();
response = PyDict_New();
PyDict_SetItemString(globals, "request", request);
PyDict_SetItemString(globals, "response", response);
obj1 = PyInt_FromLong(1);
PyDict_SetItemString(request, "count", obj1);
在本代码例子中, 字典表 request 用于 C 向 Python 传递数据, response 用于 Python 脚本向 C 程序传递数据. 使用两个字典并不是必须的, 可以只用一个. request 中有一项键名为 ‘count’ 的记录, 相当于向 Python 传递了一个名为 ‘count’ 的参数.
for(i = 0; i & 2; i++){
pobj = PyDict_GetItemString(response, "code");
printf("code: %s\n", PyString_AsString(pobj));
pobj = PyDict_GetItemString(response, "code");
printf("code: %s\n", PyString_AsString(pobj));
printf("---\n");
Python 脚本中返回名为 ‘code’ 的响应参数, 在 C 程序中将该参数的值打印出来.
Py_DECREF(obj1);
Py_DECREF(request);
Py_DECREF(response);
Py_Finalize();
使用宏 Py_DECREF 减少对象的引用计数, 以便 Python 进行垃圾收集. 最后调用 Py_Finalize() 释放资源.
void test1(){
fp = fopen("benegg.com.py", "r");
PyRun_SimpleFile(fp, filename);
fclose(fp);
PyRun_SimpleFile() 函数执行一个 Python 脚本文件.
void test2(){
PyObject *
fp = fopen("benegg.com.py", "r");
fseek(fp, 0, SEEK_END);
size = ftell(fp);
rewind(fp);
buf = malloc(size + 1);
fread(buf, 1, size, fp);
buf[size] = '\0';
PyRun_SimpleString(buf);
因为 PyRun_SimpleFile() 每执行一次都要读取一次文件, 所以可以把文件内容读取到字符缓冲中, 然后多次执行 PyRun_SimpleString(), 避免磁盘 IO 造成性能消耗.
co = Py_CompileString(buf, "benegg.com", Py_file_input);
PyEval_EvalCode((PyCodeObject *)co, globals, globals);
不过, 虽然 PyRun_SimpleString() 避免了磁盘 IO, 然后还是会在每一次执行的时候解析文本代码. 这时, 可以把代码编译成一个 PyCodeObject 对象, 然后调用 PyEval_EvalCode() 执行, 避免了多次解析造成的性能消耗.
Py_DECREF(co);
free(buf);
fclose(fp);
Python 脚本代码如下:
print "test1 - %d" % request['count']
request['count'] += 1
response['code'] = "test" + str(request['count'])
编译 C 代码:
# http://www.benegg.com
gcc -g -Wall -o c test.c -L/usr/lib/python2.5/config -lpython2.5
注意, 将路径改为你机器上的实际路径. 执行 ./c, 可以看到, 执行的结果是:
code: test2
code: test4
code: test5
code: test7
【上篇】【下篇】python爬虫——知乎(关于python的精华回答) - 简书
python爬虫——知乎(关于python的精华回答)
&strong&之前的文章都是与职位、热门文章有关的,今天一起来看一下知乎上与python相关的精华回答(主要是requests,scrapy处理的思路,编码问题)&/strong&
知乎python精华回答
1.采集的信息
&li&问题题目&/li&&li&问题对应URL&/li&&li&回答的作者&/li&&li&作者主页URL&/li&&li&回答获赞数&/li&&li&回答详情URL&/li&&/ol&&strong&主要获取以上信息,接着我们来看一下这些字段所在的位置
通过观察和分析以上字段在源码中都能找到,所以就不用像前几篇文章那样,构造参数,解析获取返回的json数据,我们可以通过lxml.etree.HTML()或者Beautifulsoup去解析(这里在通过etree解析时遇到了一些问题,在后边会进行解释)
既然不需要通过构造参数去获取数据了,所以相对来说就简单一些了,接下来我们来看一下另一个很重要的问题——分页问题&/strong&
&em&从上面两张图片我们可以看出换页之后参数&strong&page&/strong&发生了改变,很显然&strong&page&/strong&控制的是页码,明白了这一点就可以去构造URL了&/em&
urls = ['https://www.zhihu.com/topic//top-answers?page={}'.format(one) for one in range(1,51)]
&strong&解决了分页问题,就没什么难点了,接下来说一下遇到的问题和解决方法
通过Beautifulsoup解析页面
# -*- coding:utf-8 -*-
import requests
from bs4 import BeautifulSoup
from store_csv import CSV
from store_mysql import Mysql
class zhiHu(object):
baseurl = 'https://www.zhihu.com'
headers = {
"user-agent": "Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/52.0. Safari/537.36"
cookies = {
'd_c0': '"AHACIj6lFguPTkEZTVmz8MPJ8UkcuI03hag=|"',
'_zap': '-93e6-407e-68838',
'q_c1': '0d3d690c67bc4b12a163beb462e17d67|0|0',
'cap_id': '"NmFlNDgyZmMxNWQ0NGFiYmFhZThmMGM2MDVkZDM1MWM=||fb6fbc5af76e00dbaff7"',
'l_cap_id': '"ZjViYmQ0MzBkNTFjNGJjOWE5YTExZWRjMjlkNjM2YjQ=||805d8bebf3b49a8a2fc09e2f1bd870"',
'auth_type': '"c2luYQ==||245a0f575f151cba3d3c90fc5fa558"',
'token': '"Mi4wMGljWjNYRkVBNzIyRGJjZDZkMjMyZmMwM2JtMWs=||ae825a7bdc9e721853"',
'client_i': '"NTA3MzY2MzQwNA==||9a08a2c9a6c02e86da37f6d7b1028"',
'aliyungf_tc': 'AQAAAFOsE04F5QQAHVcc2i2qHTGdX1x0',
'acw_tc': 'AQAAAAnnBnQS0AcAHVcc2omDblHld+wt',
'_xsrf': '398e0b041f39355dadfc06b76ba18cdb',
's-q': 'python',
's-i': '1',
'sid': 'ob2ttqkg',
's-t': 'autocomplete',
'z_c0': 'Mi4wQUFBQ3hmbTFzUXNBY0FJaVBxVVdDeGNBQUFCaEFsVk5OVjR2V1FETW9QS19PRlExWGVjUHNOcFVoTG5mYWg1LUtR||ddc800c42c8b7dca97f34d5',
'__utma': '',
'__utmb': '.10.',
'__utmc': '',
'__utmz': '.4.utmcsr=baidu|utmccn=(organic)|utmcmd=organic',
'__utmv': '--|2=registration_date=^3=entry_date='
def getUrl(self):
urls = ['https://www.zhihu.com/topic//top-answers?page={}'.format(one) for one in range(1,51)]
for url in urls:
self.getData(url)
def getData(self,url):
data = requests.get(url, headers=self.headers, cookies=self.cookies).content.encode('utf-8')
soup = BeautifulSoup(data, 'lxml')
infos = soup.find_all('div', {'class': 'feed-item feed-item-hook folding'})
for info in infos:
item[1] = info.find('a',{'class':'question_link'}).get_text().strip()
item[1] = item[1].replace("'","=")
item[2] = self.baseurl+info.find('a',{'class':'question_link'}).get('href')
item[3] = info.find('a',{'class':'author-link'}).get_text()
item[3] = u'匿名用户'
item[4] = self.baseurl+info.find('a',{'class':'author-link'}).get('href')
item[4] = u''
item[5] = info.find('a',{'class':'zm-item-vote-count js-expand js-vote-count'}).get_text()
item[6] = self.baseurl+info.find('a',{'class':'toggle-expand'}).get('href')
item[6] = u''
self.store(item)
def store(self,item={}):
#row = [item[i] for i in range(1,7)]
#wirte.writeRow(row)
mysql.insert(item)
if __name__ == "__main__":
#firstRow = ['问题', '问题URL', '回答者', '回答者URL', '获赞', '详细信息URL']
#wirte = CSV('zhihu.csv',firstRow)
row = ['question','qurl','autuor','aurl','zan','detail']
mysql = Mysql('zhihu',row,7)
mysql.create_table()
zhihu = zhiHu()
zhihu.getUrl()
&/strong&&em&这里说明一点,from store_csv import CSV,from store_mysql import Mysql这两个是自己写的两个类,实现方法可以参考和老哥的这两篇文章,这里可以不添加cookie信息&/em&
通过etree解析页面(和之前一样都是找到循环点,然后取值,这里主要说一下遇到的问题和解决的方法)
问题&/strong&
html = requests.get(url,headers=headers)
这里有不同方式,一种是html.content,另一种是html.text之前没遇到出错的情况(通过content出现了编码问题,python版本2.7),今天遇到了就记录一下:
resp.text返回的是Unicode型的数据。
resp.content返回的是bytes型也就是二进制的数据。
也就是说,如果你想取文本,可以通过r.text。
如果想取图片,文件,则可以通过r.content。
&strong&方法&/strong&
主要说一下html.content的解决方案
selector = etree.HTML(html.content.decode('utf-8'))
通过对html.content进行解码,输出结果正常。
3.scrapy版本思路
&strong&1.使用start_requests()重写初始URL控制或者在parse函数中进行分页的控制
yield scrapy.Request(url,callback=self.parse)
&/strong&&em&代码中提到的URL指的是下一页的URL,通过获取下一页信息调用parse函数抓取信息&/em&&strong&
2.之前通过观察URL,我们发现只有page之后的数字发生了变化,所以我们可以使用爬取规则去获取不同页面的信息(给一个之前抓取智联招聘职位详情页面的规则作为参考)
# -*- coding: utf-8 -*-
from scrapy.spider import CrawlSpider,Rule
from scrapy.linkextractors import LinkExtractor
from ..items import ZlzpItem
class ZLZP_Spider(CrawlSpider):
name = 'ZLZP'
start_urls = [
'http://jobs.zhaopin.com/'
Rule(LinkExtractor(allow=('http://jobs.zhaopin.com/[a-zA-Z0-9]*\.htm',)), follow=True,
callback='parse_item')]
def parse_item(self, response):
这里使用了parse_item进行页面数据的提取(编写爬虫规则时,避免使用 parse 作为回调函数。 由于
使用 parse方法来实现其逻辑,如果覆盖了 parse方法,crawl spider 将会运行失败。)
关于 的详细使用方法可以参考官方文档或者参考相关的代码和文章
4.数据信息(mysql和csv)
通过对比动态网页(ajax)和静态网页,在思想上差别不是很大(参数+分页),在解析方式动态的一般都是通过解析json来获取数据,静态则通过Beautifulsoup、xpath、正则去获取数据。
爬爬爬,下一个网站走起!
Action 13:28:27: INSTALL. 1: MySQL Notifier 1.1.7 2: {724CDD73-430E-47DA-8F4E-7DF} Action 13:28:27: FindRelatedProducts. Searchi...
Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智能路由,微代理,控制总线)。分布式系统的协调导致了样板模式, 使用Spring Cloud开发人员可以快速地支持实现这些模式的服务和应用程序。他们将在任何分布式...
Python分布式爬虫打造搜索引擎 基于Scrapy、Redis、elasticsearch和django打造一个完整的搜索引擎网站本教程一共八章:从零开始,直到搭建一个搜索引擎。 推荐前往我的个人博客进行阅读:http://blog.mtianyan.cn/目录分章效果更...
最近学习Python爬虫,用到了Scrapy这个爬虫框架。目前Scrapy的最新版本已经达到了Scrapy 1.4,并且支持Python 3,但是网上找到的中文资料基本都是老版本的Scrapy,并且只支持到Python 2.7。于是笔者决定将Scrapy 1.4的学习过程记...
1 前言 作为一名合格的数据分析师,其完整的技术知识体系必须贯穿数据获取、数据存储、数据提取、数据分析、数据挖掘、数据可视化等各大部分。在此作为初出茅庐的数据小白,我将会把自己学习数据科学过程中遇到的一些问题记录下来,以便后续的查阅,同时也希望与各路同学一起交流、一起进步。...
每一次走在马路上,看到一个漂亮姑娘我就是想看,这是什么毛病呢。我觉得吧,人家打扮出门,就是让人去欣赏的,没有其它意思大家说对不对。总有朋友会说我离不开女人,那些不懂欣赏美的人啊……
甲醛是一种挥发性很强的有机化合物,污染程度较高,是室内空气的主要污染物之一。下面小编为大家介绍除甲醛活性炭的相关知识。 甲醛是一种挥发性很强的有机化合物,污染程度较高,是室内空气的主要污染物之一。我国公共场所卫生标准中规定甲醛是必测项目之一。众所周知,甲醛对人体健康影响很大...
故事发生在14年7月份,地点,厦门。故事背景,我和大学宿舍的哥哥们一起去电子厂做暑假工。
那天下了夜班,我如往常一般拖着疲惫的身体回到了宿舍,困意侵占了我的意识,饥饿则肆虐着我的身体。
我推开宿舍门,看见老五站在卫生间门口,应该是要准备洗澡,我没有和...
三月,踏着阳光,伴着微风,和文友们来到了蜀南竹海。 时间,距离我第一次去,已经过去了七年多。 竹子们仍然是那么青翠、挺拔,富有生机与活力。这一切,似乎都不曾因时间而改变。仿佛我从未来过,又好像从不曾离开。 一排排整齐的竹子傲然挺立,微风拂过,枝叶摇曳,如久违的朋友对我挥手。...早就在学习
的教程时知道了
这个工具了(因为在安装时还报了错,因为setuptools的版本问题),不过一直没有机会学习和使用。终于在试着发布
时用了一下。不过在使用的过程中遇到一些问题,最近也解决了。
中使用的setup.py脚本如下:
import ez_setup # From http://peak.telecommunity.com/DevCenter/setuptoolsez_setup.use_setuptools()
import setup, find_packages
setup(&&& name = &EasyWizard&,&&& version = &0.1&,&&& url = ‘http://wiki.woodpecker.org.cn/moin.cgi/EasyWizard/’,&&& author = ‘limodou’,&&& author_email = ‘’,&&& description = ‘A easy way to create Wizard in ‘,&&& license = ‘GPL’,&&& packages = find_packages(),&&& package_data ={&&&&&&& ‘test’: ['*.jpg'],&&& },&&& scripts = ['EasyAdmin.py'],)
import ez_setup # From http://peak.telecommunity.com/DevCenter/setuptoolsez_setup.use_setuptools()
是为了当setuptools不存在时,有了这两个会自动从网上安装所需要的setuptools包。
后面就是安装脚本了。大部分没什么解释的。其中
packages = find_packages(),
会自动查找当前目录下的所有模块。因此只要把setup.py放在你要打包的模块之上即可由find_packages自动来查找要打包的模块。package_data是用来包括应用所用到的其它数据文件。scripts是可以将脚本拷贝到
的Scripts目录下。因此在你安装 EasyWizard 时,EasyAdmin.py 会自动安装到 /Scripts 目录下,因此就可以方便地执行 EasyAdmin.py 了。
那么我遇到什么问题呢?就是某些不在模块中的文件,还有上面*.jpg文件并未打进包里去,试来试去都不得其解。可是我在 SetupTools 文档中看到这么一句话:
setuptools enhances the distutils’ default algorithm for source file selection, so that all files managed by CVS or
in your project tree are included in any source distribution you build. This is a big improvement over having to manually write a MANIFEST.in file and try to keep it in sync with your project. So, if you are using CVS or , and your source distributions only need to include files that you’re tracking in revision control, don’t create a a MANIFEST.in file for your project. (And, if you already have one, you might consider deleting it the next time you would otherwise have to change it.)
于是我启动了SubVersion来将我的EasyWizard设置进去(以前没加进去)。这下都解决了,我想要的文件都加进去了,而且连ez_setup.py,README.txt也自动加到包里去了。原来如此。
只不过现在安装时会生成一个.egg文件(就是一个压缩文件),而不是生成一个目录,我现在还知道如何改掉。
不过使用这个工具的确有趣。与之相配套的还有一个easy_install,它可以自动下载包。不过这个SetupTools也可以设置相关的包和版本,如果没有安装的话会自动下载并安装。
— limodou @ 8:27 pm
本站所有内容采用许可证。
Pythoner in 中国
Python开源项目
我的开源项目没有更多推荐了,
加入CSDN,享受更精准的内容推荐,与500万程序员共同成长!}

我要回帖

更多关于 c 调用c 的文章

更多推荐

版权声明:文章内容来源于网络,版权归原作者所有,如有侵权请点击这里与我们联系,我们将及时删除。

点击添加站长微信