C++调用python,并抓取每日一句名言

23 篇文章 4 订阅
10 篇文章 6 订阅

作者:非妃是公主
专栏:《笔记》《C++》 《python学习》
个性签:顺境不惰,逆境不馁,以心制境,万事可成。——曾国藩

在这里插入图片描述

前言

前几天利用C++调用Python脚本,在进行语言融合的过程中,踩到了好多坑,在此总结一下!

C++执行python代码

  • 首先我们需要配置C++调用python所需要的链接库,将include和libs文件夹放到工程文件目录下(和.sln文件放在一起)
    在这里插入图片描述
  • 两个文件在python的安装目录下,比如我的:
    在这里插入图片描述
  • 在项目中配置环境依赖
    右键项目-》选择属性-》C/C+±》常规-》附加包含目录,添加include文件夹的相对路径(../include),../为返回上一级目录。(当前cpp的上一级目录就是include所在目录)
    在这里插入图片描述
    右键项目-》选择属性-》选择连接器-》常规-》附加库目录-》添加libs的相对目录../libs../为返回上一级目录。(当前cpp的上一级目录就是libs所在目录)。

在这里插入图片描述

  • 点击应用,然后关闭窗口,编译器切换到release,选择64位,这块要根据子集python的版本,因为我的是64位,就只能在MSVC64的环境下运行,而且我的python没有安装python在MSVC下的调试器,所以只能在release下运行(如果安装的时候没有特别注意,都是我这样安装的)。
    在这里插入图片描述
  • 运行下面的代码
    在这里插入图片描述
#include <Python.h>
int main(int argc, char* argv[]) {
	Py_Initialize();
	PyRun_SimpleString("print('hello world')\n");
	Py_Finalize();
	return 0;
}
  • 控制台弹出以下信息
    在这里插入图片描述
    这是在说明,我们没有设置PYTHONHOMEPYTHONPATH这两个环境变量。
    新建PYTHONHOME用户变量,变量值设置为Anaconda3所在的目录下即可(为了找到python.exe)
    在这里插入图片描述
    同样,新建PYTHONPATH用户变量,变量值与PYTHONHOME相同
    这样用户变量就配置好了。
    在这里插入图片描述
    重新运行,发现还是报错(这是由于环境变量需要重启后才能生效,重启电脑)。
    在这里插入图片描述
  • 重启电脑后,发现运行正常了,打出了Hello World这里注意一下,这个环境变量会对虚拟环境造成影响,如果用完之后要用其它虚拟环境,一定要注意删除这两个环境变量,否则会产生无法识别的错误这篇文章中有记录不删除这两个环境变量会产生的问题
    在这里插入图片描述
  • 对以上代码进行简单的说明,如下图:
    在这里插入图片描述
  • 上面我们解决了如何利用C++执行python代码的问题,那么很多时候我们的python代码都是比较复杂的(包括分支循环,作用域等),用字符串表示起来是不方便的,是否可以存在一种可以直接调用py文件的方法呢?答案是肯定的。

C++调用.py文件

我们新建C++工程,然后按照上面进行目录的配置(libs和include),编译环境的切换(release,X64)。
然后新建.py文件,并放在工程文件名/X64/release文件夹下,与工程的.exe文件放在一起,不然会找不到。
在这里插入图片描述

在这里插入图片描述
代码如下:

#include <Python.h>
#include <iostream>
#include <string>
using namespace std;

int main(int argc, char* argv[]) {
	Py_Initialize();// Python 接口初始化

	PyObject* pModule = NULL; // 模块句柄
	PyObject* pFunc = NULL;// 函数句柄
	PyObject* pName = NULL;// 
	pModule = PyImport_ImportModule("Test"); // 文件名
	if (pModule == NULL) // 如果没找到返回
	{
		cout << "没找到" << endl;
		return 0;
	}
	pFunc = PyObject_GetAttrString(pModule, "Fun"); // 函数名
	PyObject* pArgs = PyTuple_New(2);// 函数调用的参数传递均是以元组的形式打包的,2表示参数个数
	PyTuple_SetItem(pArgs, 0, Py_BuildValue("i", 222));// 0 表示第一个参数 i表示 int类型 222表示具体参数
	PyTuple_SetItem(pArgs, 1, Py_BuildValue("i", 444));// 1 表示第二个参数 i表示 int类型 444表示具体参数
	PyObject* pReturn = PyObject_CallObject(pFunc, pArgs);// 调用函数

	int nResult;// 储存结果的C++类型
	PyArg_Parse(pReturn, "i", &nResult);// i表示转换成int型变量
	cout << nResult << endl; // 输出
	Py_Finalize();// 结束Python接口初始化
	return 0;
}

至于返回值的传递是一个比较麻烦的问题,由于这是一个老接口了,所以并不是很好用,在参数传递的过程中我踩了好多坑,最终一种比较好用的解决方法就是将返回值写进文件,然后在C++中写代码去读文件,当然这样效率会比较低,但是相信使用C++和python进行语言融合的项目都是想短期实现,对性能要求不高的。自己写的一个爬虫程序效果如下:
每运行一次OneNoteEveryDay.exe会生成一个OneNoteEveryDay.txt。
在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

C++调用爬虫

爬虫代码如下,有兴趣的友友可以尝试一下,还挺好玩的!(^o^)!

import random
from bs4 import BeautifulSoup
import requests
import ctypes as ct
import re


def Fun():
    res = requests.get('http://quotes.toscrape.com/')
    res.raise_for_status()
    html = res.text  # 页面内容
    soup = BeautifulSoup(html, 'lxml')

    items = soup.find_all('span', class_='text')
    words = []

    for item in items:
        words.append(item.text)
        # f.write(output + '\n')

    f = open("OneNoteEveryDay.txt", 'w')
    number = random.randint(0, len(words) - 1)
    words[number] = re.sub("“", "", words[number])
    words[number] = re.sub("”", "", words[number])
    f.write(words[number])
    f.close()

  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Cherries Man

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值