Как я могу успешно вызвать функцию Python из С++ в том же экземпляре?

эй, я пытаюсь встроить Python Selenium в C++, но мне удалось просто открыть браузер и получить элемент. Как я могу успешно открыть браузер и выполнить поиск HELLO внутри панели поиска Google?

#define PY_SSIZE_T_CLEAN
#include <python/Python.h>
#include <conio.h>
#include <iostream>
#include <string>
#include <filesystem>
#include <python/pyhelper.hpp>


using namespace std;
#define PYSRCDIR "/PythonSrc/"

PyObject* pName, * pModule, * pFunc;
PyObject* pArgs, * pValue;


inline int  __initialize_path(string __file) {
    file = __file;
    
    std::filesystem::path path = std::filesystem::current_path();
    std::string _path = path.string();
  
    std::replace(_path.begin(), _path.end(), '\\', '/');
    try {
        PyRun_SimpleString("import sys");
    }
    catch (...) {
        cout << "cpp >> INITIALIZE with <Py_Initialize();> first\n";
        return -1;
    }
    PyRun_SimpleString((string("sys.path.append(\"") + _path + string(PYSRCDIR) + string("\")")).c_str());
    
    pName = PyUnicode_DecodeFSDefault(file.c_str());
    /* Error checking of pName left out */

    pModule = PyImport_Import(pName);
    Py_DECREF(pName);

    return 0;
}
/**
 * It calls a python function from C++
 * 
 * @param file The name of the python file to be executed. It should be located in PYSRCDIR dir
 * @param funcptr The name of the function to call.
 * 
 * @return The return value is the status.
 */
inline int __callpy_noarg(string funcptr) {
   
    if (pModule != NULL) {
        pFunc = PyObject_GetAttrString(pModule, funcptr.c_str());
        /* pFunc is a new reference */

        if (pFunc && PyCallable_Check(pFunc)) {
            pValue = PyObject_CallObject(pFunc , NULL);
        }
        else {
            /* Checking if there is an error. If there is an error, it prints it out. */
            if (PyErr_Occurred())
                PyErr_Print();
            fprintf(stderr, "Cannot find function \"%s\"\n", funcptr);
        }
        Py_XDECREF(pFunc);
        Py_DECREF(pModule);
    }
    else {
        PyErr_Print();
        fprintf(stderr, "Failed to load \"%s\"\n", file.c_str());
        return 1;
    }
    
    return 0;
}
 /**
  * It calls a Python function with args from C++.
  * 
  * @param file The name of the python file to be executed.
  * @param funcptr The name of the function to call.
  * @param args A vector of strings that are the arguments to pass to the Python function.
  * 
  * @return The return value is the status.
  */
inline int __callpy_warg(string funcptr, vector<string>* args) {
     
     if (pModule != NULL) {
         pFunc = PyObject_GetAttrString(pModule, funcptr.c_str());
         /* pFunc is a new reference */

         if (pFunc && PyCallable_Check(pFunc)) {
             pArgs = PyTuple_New(args->size());
             for (i = 0; i < args->size(); ++i) {
                 string str = args->at(i);
                 pValue = PyUnicode_FromString(str.c_str());
                 if (!pValue) {
                     Py_DECREF(pArgs);
                     Py_DECREF(pModule);
                     fprintf(stderr, "Cannot convert argument\n");
                     return 1;
                 }
                 /* pValue reference stolen here: */
                 PyTuple_SetItem(pArgs, i, pValue);
             }
             pValue = PyObject_CallObject(pFunc, pArgs);
             Py_DECREF(pArgs);
             if (pValue != NULL) {
                 printf("Result of call: %ld\n", PyLong_AsLong(pValue));
                 Py_DECREF(pValue);
             }
             else {
                 Py_DECREF(pFunc);
                 Py_DECREF(pModule);
                 PyErr_Print();
                 fprintf(stderr, "Call failed\n");
                 return 1;
             }
         }
         else {
             if (PyErr_Occurred())
                 PyErr_Print();
             fprintf(stderr, "Cannot find function \"%s\"\n", funcptr.c_str());
         }
         Py_XDECREF(pFunc);
         Py_DECREF(pModule);
     }
     else {
         PyErr_Print();
         fprintf(stderr, "Failed to load \"%s\"\n", file.c_str());
         return 1;
     }
     
     return 0;
 }


int main()
{
    CPyInstance inst;

    __initialize_path("pyemb3");
    std::vector<string>* vec1 = new std::vector<string>;
    vec1->push_back(" ");
    __callpy_warg("init_selenium", vec1);
    delete vec1;

    std::vector<string>* vec2 = new std::vector<string>;
    vec2->push_back("https://www.google.com/");
    __callpy_warg("get_search", vec2);
    delete vec2;

    std::vector<string>* vec3 = new std::vector<string>;
    vec3->push_back("q");
    __callpy_warg("get_elem_NAME", vec3);
    delete vec3;

    std::vector<string>* vec4 = new std::vector<string>;
    vec4->push_back("0");
    __callpy_warg("click_ELEMENT", vec4);
    delete vec4;


    std::vector<string>* vec5 = new std::vector<string>;
    vec5->push_back("0");
    vec5->push_back("HELLO");
    __callpy_warg("type_ELEMENT", vec5);
    delete vec5;

    std::vector<string>* vec6 = new std::vector<string>;
    vec6->push_back("0");
    vec6->push_back('\ue007');// enter key unicode
    __callpy_warg("type_ELEMENT", vec6);
    delete vec6;



   
}

поэтому в основной функции я вызываю некоторые функции, определенные внутри этого файла python

# It imports the necessary modules to run the code.

from selenium.webdriver.chrome.options import Options
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
import time
import threading
import chromedriver_autoinstaller

chromedriver_autoinstaller.install()

global option
driver = ""
elements_list = []




def init_selenium(param):
    options = Options()
    if not param == "":
        paramlist = param.split(" ");
    else:
        print("init_selenium --NO ARGS")
    if "headless" in paramlist:
        options.add_argument("--headless")
        print("init_selenium --HEADLESS")

    global driver;
    driver = webdriver.Chrome(options=options)


def get_search(PATH):
    global driver;
    if not PATH == "":
        driver.get(PATH)
    else:
        print("get_search --NO PATH SPECIFIED")


def wait_elem_XPATH(ELEMDATA , TIME):
    global driver;
    try:
        element1 = WebDriverWait(driver, int(TIME)).until(
            EC.presence_of_element_located((By.XPATH, ELEMDATA)))
    except:
        print("wait_elem_XPATH --INVALID ARGS")

def get_elem_XPATH(ELEMDATA):
    global driver;
    element3 = driver.find_element_by_xpath(ELEMDATA)
    global elements_list;
    elements_list.append(element3);


def get_elem_NAME(ELEMDATA):
    global driver;
    element3 = driver.find_element_by_name(ELEMDATA)
    global elements_list;
    elements_list.append(element3);

def click_ELEMENT(ELEMNUMBER):
    global elements_list;
    elements_list[int(ELEMNUMBER)].click()

def type_ELEMENT(ELEMNUMBER , TEXT):
    global elements_list;
    elements_list[int(ELEMNUMBER)].send_keys(TEXT)

def driver_QUIT():
    global driver;
    driver.quit()


def driver_WAIT(sec):
    driver.implicitly_wait(int(sec)) # seconds

ошибка говорит, что он не может найти функции, но может найти другие....

AttributeError: '_collections._deque_iterator' object has no attribute 'click_ELEMENT'
Cannot find function "click_ELEMENT"
AttributeError: 'builtin_function_or_method' object has no attribute 'type_ELEMENT'
Cannot find function "type_ELEMENT"
AttributeError: 'AttributeError' object has no attribute 'type_ELEMENT'
Cannot find function "type_ELEMENT"

ссылка на проект github: https://github.com/Vasika-uso/Selenium-embedded-in-cpp

Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
2
0
35
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Я думаю, вы можете создать файл .dll формы .py и передать его при компиляции кода на С++. Вы можете использовать pyinstaller для преобразования файлов .py в исполняемый файл со всеми необходимыми пакетами в формате .dll.

Шаг 1. pip установите pyinstaller,

Шаг 2. Новый файл Python назовем его code.py.

шаг 3. Напишите несколько строк кода, т.е. print("Hello World")

Шаг 4. Откройте командную строку в том же месте и напишите pyinstaller code.py, нажмите Enter. Последний шаг: в том же месте будут созданы две папки с именем build, dist. внутри папки dist есть код папки, а внутри этой папки есть исполняемый файл code.exe вместе с необходимыми файлами .dll.

Другие вопросы по теме