【问题标题】:Python Headless Browser for GAE用于 GAE 的 Python 无头浏览器
【发布时间】:2025-12-21 04:45:12
【问题描述】:

我正在尝试在 Google Appengine 上将 Angular.js 客户端与 webapp2 一起使用。

为了解决 SEO 问题,我们的想法是使用无头浏览器来运行 javascript 服务器端并将生成的 html 提供给爬虫。

有没有在谷歌应用引擎上运行的 Python 无头浏览器?

【问题讨论】:

    标签: python google-app-engine headless-browser


    【解决方案1】:

    这是一个超级元的想法。 Web 服务器使用无头 Web 浏览器来完成 Web 请求以呈现页面并返回结果。唷。

    查看以下关于无头浏览器的答案,特别注意基于 Python 的浏览器。

    无头浏览器问题:headless internet browser?

    看起来支持 Javascript 的都使用 WebKit 并且需要 PyQt 或 Pyside。这意味着由于存在运行时限制,您将无法在 App Engine 上运行它们。

    出于 SEO 的目的,我建议您进行某种用户代理检测,并使用 Jinja2 模板或其他东西发出您页面的超级缩小版本。无论如何,您可能会获得更好的性能。

    【讨论】:

      【解决方案2】:

      现在可以使用自定义运行时在 App Engine Flex 上完成,所以我添加了这个答案,因为这个问题是谷歌弹出的第一件事。

      我将此自定义运行时基于我的其他 GAE flex 微服务,该微服务使用预构建的 python 运行时

      项目结构:

      webdrivers/
      - geckodriver
      app.yaml
      Dockerfile
      main.py
      requirements.txt
      

      app.yaml:

      service: my-app-engine-service-name
      runtime: custom
      env: flex
      entrypoint: gunicorn -b :$PORT main:app --timeout 180
      

      Dockerfile:

      FROM gcr.io/google-appengine/python
      RUN apt-get update
      RUN apt-get install -y xvfb
      RUN apt-get install -y firefox
      LABEL python_version=python
      RUN virtualenv --no-download /env -p python
      ENV VIRTUAL_ENV /env
      ENV PATH /env/bin:$PATH
      ADD requirements.txt /app/
      RUN pip install -r requirements.txt
      ADD . /app/
      CMD exec gunicorn -b :$PORT main:app --timeout 180
      

      requirements.txt:

      Flask==0.12.2
      gunicorn==19.7.1
      selenium==3.13.0
      pyvirtualdisplay==0.2.1
      

      main.py

      import os
      import traceback
      
      from flask import Flask, jsonify, Response
      from selenium import webdriver
      from pyvirtualdisplay import Display
      
      app = Flask(__name__)
      
      # Add the webdrivers to the path
      os.environ['PATH'] += ':'+os.path.dirname(os.path.realpath(__file__))+"/webdrivers"
      
      @app.route('/')
      def hello():
          return 'Hello!!'
      
      @app.route('/test/', methods=['GET'])
      def go_headless():
          try:
              display = Display(visible=0, size=(1024, 768))
              display.start()
              d = webdriver.Firefox()
              d.get("http://www.python.org")    
              page_source = d.page_source.encode("utf-8")
              d.close()
              display.stop()
              return jsonify({'success': True, "result": page_source[:500]})
          except Exception as e:
              print traceback.format_exc()
              return jsonify({'success': False, 'msg': str(e)})
      
      if __name__ == '__main__':
          app.run(host='127.0.0.1', port=8080, debug=True)
      

      从这里下载 geckodriver (linux 64):

      https://github.com/mozilla/geckodriver/releases

      其他说明:

      本地测试:

      docker build . -t my-docker-image-tag
      docker run -p 8080:8080 --name=my-docker-container-name my-docker-image-tag
      

      部署到应用引擎:

      gcloud app deploy app.yaml --version dev --project my-app-engine-project-id
      

      【讨论】:

      • 感谢您的深入回答。当时,这很难,现在我们试图解决的问题变得微不足道,不再重要。希望这将有助于其他开发人员并将他们推向正确的方向。干杯!
      • 这很棒。有什么原因不能与 Chromdriver 一起使用吗?
      • 我想它应该可以工作,但请参阅我的Other notes: 部分。我遇到了很多奇怪的问题,所以请准备好进行一些修补。