經驗拾憶(純手工)=> Python版-Docker使用selenium簡單示例

Dockerfile內容如下

FROM python
RUN pip install -i http://pypi.douban.com/simple \
    requests selenium retrying --trusted-host pypi.douban.com

docker-compose.yaml內容如下

version: "3.7"
services:
  myspider:
    build: .
    volumes:  # 數據卷映射
      - /root/mycode:/root/mycode
    command: python /root/mycode/1.py
    # 依賴下方 selenium服務,注意此依賴僅僅能做到
    # selenium服務先啓動, myspider服務後啓動(有的服務內部程序啓動的快,有的慢)
    # 根本程度上還是解決不了 完全依賴 的 問題, 因此可以用延時處理等方法
    depends_on:
      - selenium
  selenium:
    image: selenium/standalone-chrome # 拉取鏡像完成自動化全套配置
    ports:
      - "4444:4444"
    shm_size: 2g  # 設置主機共享內存2g
    hostname: selenium    # 其他容器可以用此名來訪問 eg: http://selenium:4444/

爬蟲腳本代碼1.py如下

import requests
from selenium import webdriver
from selenium.webdriver.common.desired_capabilities import DesiredCapabilities
from retrying import retry

# 注:docker-compose.yaml中的depends_on那裏提到過:
# 服務可以起到先後依賴的效果。
# 而服務中的啓動程序,並不能達到完全的依賴(啓動速度相當的情況下,誰快誰慢運氣成分)

# 可以通過加延時來控制先後順序
# import time    
# time.sleep(3)    # 這種睡眠延時方式,或多或少不太精確,可以用下面的 retrying代替之

# 也可以通過 retrying模塊裝飾實現
# retrying用法,可參考  https://segmentfault.com/a/1190000019301761#articleHeader17
@retry(
    stop_max_attempt_number = 10000,
    stop_max_delay = 10*1000,
)
def verify_request():
    response = requests.get("http://selenium:4444", timeout=0.5)
    print(response)
verify_request()

# 下面基本上是連接Docker Selenium服務的固定寫法,可當作模板套
with webdriver.Remote(
    command_executor='http://selenium:4444/wd/hub',   # selenium爲docker-compose的host名
    desired_capabilities=DesiredCapabilities.CHROME
) as driver:
    driver.get('http://www.baidu.com')
    # 這裏使用絕對路徑, 否則數據卷映射失敗
    # 映射部分在上面 docker-compose.yaml 的 volumes部分
    with open('/root/mycode/test.html', 'w') as f:    
        f.write(driver.page_source)
        print('寫入成功')

踩坑

selenium 因爲有服務端程序,所以我們可以在遠程"雲服務器用Docker容器部署"
容器部署後。。。。
"只能雲服務器中訪問,
不能在遠程服務器訪問。
(
    其實根本不需要在遠程服務器訪問的,某種邪惡的念頭,讓我走了彎路。。。一根筋想要遠程訪問
    其實代碼同是部署在容器中的,容器互通是完全OK的。
    但如果你也想試試遠程訪問, 它卻真的無法訪問。。。。。。。。。。。
)"

(
    我的認知裏,既然雲服務器宿主機可以訪問容器內部 啓動的服務端程序 
    而遠程服務器不能訪問容器內部的  啓動的服務端程序。。。。那一定是容器和宿主機連通配置問題阿。
    帶着這個思路,找了很久很久, 然並卵。。。
)

實在沒辦法了。。科學上網,搜一下這個問題的解決方案吧。
後來無意中發現,客戶端現在居然可以連上了。。 
後來測試,哇, 果然是 需要科學上網才能 遠程訪問到,此服務端。。。

但我現在還沒有明白,爲什麼我雲服務器宿主機, 不需要科學上網,也能成功訪問內部容器的服務端??
(雖然這個疑惑沒有必要)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章