首页 > 解决方案 > 使用 Electron JS 在 Python 和 React 之间实时交换数据

问题描述

我必须实现一个网络抓取工具,我选择使用带有 react 和 python 的电子 js。

我可以集成python并在电子中使用python shell做出反应,如下所示,

反应代码

import React from 'react';
var path = require("path")

const {PythonShell} = require("python-shell");
const city = 'XYZ';
  var options = {
    scriptPath : path.join(__dirname, '../../python/'),
    args : [city]
  }

class App extends React.Component {
constructor(props) {
  super(props);
}


componentDidMount() {
  var shell = new PythonShell('main.py', options); //executes python script on python3

  shell.on('message', function(message) {
    console.log('message', message)
  })
}


render (){
  return (
   <div className="header">
        <h1>Hello, World, {this.state.test}</h1>
   </div>
  )
 }
}

export default App;

Python代码

import sys
import requests
from bs4 import BeautifulSoup
from queue import Queue, Empty
from concurrent.futures import ThreadPoolExecutor
from urllib.parse import urljoin, urlparse

city = sys.argv[1]

class MultiThreadScraper:

def __init__(self, base_url):

    self.base_url = base_url
    self.root_url = '{}://{}'.format(urlparse(self.base_url).scheme, urlparse(self.base_url).netloc)
    self.pool = ThreadPoolExecutor(max_workers=5)
    self.scraped_pages = set([])
    self.to_crawl = Queue()
    self.to_crawl.put(self.base_url)

def parse_links(self, html):
    soup = BeautifulSoup(html, 'html.parser')
    links = soup.find_all('a', href=True)
    for link in links:
        url = link['href']
        if url.startswith('/') or url.startswith(self.root_url):
            url = urljoin(self.root_url, url)
            if url not in self.scraped_pages:
                self.to_crawl.put(url)

def scrape_info(self, html):
    return

def post_scrape_callback(self, res):
    result = res.result()
    if result and result.status_code == 200:
        self.parse_links(result.text)
        self.scrape_info(result.text)

def scrape_page(self, url):
    try:
        res = requests.get(url, timeout=(3, 30))
        return res
    except requests.RequestException:
        return

def run_scraper(self):
    while True:
        try:
            target_url = self.to_crawl.get(timeout=60)
            if target_url not in self.scraped_pages:
                print("Scraping URL: {}".format(target_url))
                self.scraped_pages.add(target_url)
                job = self.pool.submit(self.scrape_page, target_url)
                job.add_done_callback(self.post_scrape_callback)
        except Empty:
            return
        except Exception as e:
            print(e)
            continue
if __name__ == '__main__':
   s = MultiThreadScraper("http://websosite.com")
   s.run_scraper()

在 React 中执行 python shell 后,我可以获得所有抓取 URL,但我希望在 React 前端实时获取所有 URL。

以下 React 代码执行 python 代码并给出最终结果

var shell = new PythonShell('main.py', options); //executes python script on python3

此 React 代码用于通过简单的“打印”语句从 python 脚本接收消息。

pyshell.on('message', function (message) {
 console.log(message);

});

有没有办法在执行python代码时实时得到结果?

标签: pythonpython-3.xreactjselectron

解决方案


在 python 中使用sys.stdout.flush()after print 语句。

参考:sys.stdout.flush() 的用法


推荐阅读