7

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

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

是否有任何在谷歌应用引擎上运行的 Python 无头浏览器?

4

2 回答 2

11

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

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

项目结构:

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

应用程序.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

要求.txt:

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

主文件

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

其他注意事项:

  • 请注意您正在使用的 geckodriver、firefox 和 selenium 的版本,因为它可能是 finnickey,会出现此错误WebDriverException: Message: Can't load the profile. Possible firefox version mismatch. You must use GeckoDriver instead for Firefox 48+. Profile Dir: /tmp/tmp 48P If you specified a log_file in the FirefoxBinary constructor, check it for details.
  • 除非您使用的是旧版 geckodriver/firefox,否则不要设置DesiredCapabilities().FIREFOX["marionette"] = False https://github.com/SeleniumHQ/selenium/issues/5106
  • display = Display(visible=0, size=(1024, 768))需要修复此错误:如何修复 Selenium WebDriverException:浏览器似乎在我们连接之前已退出?

在本地测试:

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
于 2018-07-19T15:55:07.857 回答
3

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

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

无头浏览器问题:无头互联网浏览器?

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

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

于 2013-07-28T02:01:06.337 回答