구글은 페이지 모드 서비스를 가져 헤더없는 브라우저를 설정 laravel-> PHP-> python-> 고정 표시기!

 배경 :

회사 관리 시스템은 사용자 정의 기업을 구성하는 과정을 중요한 정보를 숨기고 간소화하기 위해 관련 구성 등 기업 마이크로 기업 페이지 편지 이름, 로고, 등의 매개 변수 및 작업의 수에 대한 정보를 얻기 위해 필요

초판은 쿠키가 법적 지위를 얻기 위해 사용할 수 있습니다, 로그인 쿠키를 얻기 위해 스캔 코드를 달성 자유롭게 페이지 인터페이스를 요청할 수 있으며, 시뮬레이션 작업의 첫 번째 버전은 주로 어떤 인터페이스, 아무와 함께 사용하지 할 수있는 인터페이스를 잡힌

이 버전의 소스 페이지 두 번째 버전이 더 인터페이스, 렌더링되지 수있는 문서의 페이지 후 일반 페이지 가져 오기가없는 최대 렌더링되는 일부 구성 매개 변수 JS가 필요, 우리는 기어와 작동하는 헤더없는 브라우저를 사용할 수 페이지

구현 과정 :

laravel 버전

Laravel 개발 프로젝트는 첫번째 생각은 프레임 워크에 통합되어, 사용하는 것입니다, 그리고 laravel 관련 구성 요소를 제공한다 : Laravel 황혼

이 플러그인은 브라우저 테스트를 위해 사용되지만, 종종 페이지를 크롤링하는 데 사용되지만

잘 생긴 ,,하지만 설치가 작동을하지 않을 때,

 

PHP 버전

그럼 코드에 직접 그것을 자신을 실현

당신이 페이지로 바로 이동할 수 있도록 직접 로그인 쿠키에 대한 클래스, 새로운 시간에 자신의 패키지는 이전 건너

QyWebChrome 클래스 
{ 
  # 구글 크롬은 드라이버의 해당 버전 https://sites.google.com/a/chromium.org/chromedriver/downloads 다운로드 
    = 개인 envchromedriverpath을 $ 'webdriver.chrome.driver =는 / usr / 빈 / chromedriver'; 

    개인 $ 드라이버, 

    개인 $ 오류, 

    공공 함수 __construct ($의 cookie_str) 
    { 
        하는 putenv ($ this-> envchromedriverpath); 
        $ :: 기능 = DesiredCapabilities 크롬 (); 
// $ cookie_str = '= sssf1; _gxxxx = sdfn 1.' ; 

        // '- 머리가없는'헤드리스 (headless) 모드 : 브라우저가 백그라운드에서 실행되고, 서버 데스크탑 환경에 설치되어있는 브라우저가 제거하는 전체 프로세스를 미리 볼 수 있습니다 
        $ capabilities-> setCapability ( 
            'chromeOptions를'
            [ '인수'=> [ ' --disable-GPU', '- 헤드리스', '- 사용자 에이전트 = 모질라 / 5.0 (윈도우 NT 10.0; Win64를; 64) AppleWebKit / 537.36 (게코 같은 KHTML) 크롬 / 사파리 71.0.3578.80 / 537.36 ']] 
        ); 

        $ this-> 드라이버 = ChromeDriver :: 시작 ($), 널 (null) 기능, 

        SLEEP (3); 
        // 점프 페이지에 뛰어 싶었 후 로그인 쿠키를 설정 인덱스로 이동하는 페이지 
        $ this-> 드라이버 -> GET ( 'https://work.weixin.qq.com/'); 
        SLEEP (2); 
        // 쿠키 추가 
        ) this-> 드라이버 ->를 (관리 $를 -> deleteAllCookies을 () ; 
        SLEEP (1.); 
        $ = 폭발 cookie_arr ( ','$의 cookie_str) 
        ($ $ cookie_arr cookpair는 AS) {foreach 문을 
            $ = 폭발 ( '='$의 cookpair)를 cookie_item;
            $ 쿠키 = [
                '이름'=> 트리밍 ($ [0] cookie_item) 
                '값'=> 트리밍의 ($ cookie_item [. 1), 
                '도메인'=> 'work.weixin.qq.com' 
                'Http 만'=> FALSE로를 
                '패스'=> '/' 
                , => false로 '보안' 
            ] 
            -; $가 this-> 드라이버 ->) (관리> 대해 addCookie ($ 쿠키) 
        } 

        . (1) SLEEP; 

    } 

    공개 __destruct 함수 () 
    { 
        $ this-> 드라이버 ->) (닫기; 
    } 

    내 기업 정보 페이지에 // 점프 
    공공 getProfilePage 기능 () { 
        $ 데이터 = []; 
        $ this-> 드라이버 -> GET ( 'HTTPS ://work.weixin.qq.com/wework_admin/frame#profile/enterprise ');
        SLEEP. (3); 
        // 비즈니스 logoUrl 

        // 기업 지칭 
        $ companynamespan = $ this-> 드라이버 -> findElement ( 
            WebDriverBy :: 클래스 이름 ( 'profile_enterprise_item_shareName') 
        ); 
        $ 데이터 [ '회사 명'] = $ companynamespan-> gettext에 ( ) 

        ; 데이터 $를 반환 
    } 

    HTML 렌더링 가져 // 
    // $ 드라이버 -> getPageSource (); 
    / * 
     webdriver 주로 우리의 운영 요소에 두 개의 DOM API를 제공 

RemoteWebDriver :: findElement (WebDriverBy) 단일 요소를 얻기를 
RemoteWebDriver :: findElements (WebDriverBy가) 요소의 목록을 얻으려면 
WebDriverBy 쿼리 객체는 다음과 같은 몇 가지 일반적으로 사용되는 방법으로 제공합니다 

ID를 기반으로 요소를 찾을 수 WebDriverBy :: ID ($ id를) 
WebDriverBy :: 클래스 이름 ($ 클래스 명)에 따라 클래스 요소를 찾기
WebDriverBy 일반적 CSS 선택 쿼리 따른 :: cssSelector ($의 selctor) 
요소 이름에 기초 WebDriverBy :: 이름 ($ 이름) 쿼리 속성 
WebDriverBy :: 링크 텍스트 ($ 텍스트)의 문의에 기반한 앵커 텍스트 표시 소자 
WebDriverBy :: 태그 이름 ( 레이블 이름에 따라 $ 태그 이름) 요소는 쿼리 
WebDriverBy이 :: XPath 쿼리 식에 대한 XPath는 ($의 XPath는이),이 매우 강력 
     * / 

    // 스크린 샷 
    공개 기능 takeScrenshot ($ savepath = "test.png") { 
        $ this-> 드라이버 - > takeScreenshot의 ($ savepath) 
    } 

    / ** 
     * @return 혼합 
     * / 
    공용 함수은 GetError는 () 
    { 
        $ this-> 오류를 반환; 
    } 

    / ** 
     * @param 혼합 $ 에러 
     * / 
    공용 함수 setError ($ 에러) : 무효 
    { 
        $ this-> $ 에러 = 에러; 
    } 
}

  배포 :

구글 크롬 설치

냠 구글 크롬을 설치

  설치가 완료 인수 크롬 버전입니다 후

밸리에서 해당 chromedriver https://sites.google.com/a/chromium.org/chromedriver/downloads 아이 노래를 다운로드

페이지 GoogleChrome을 주로하고 chromedirver 사이의 대응이 같다

 

 

다양한 버전은 여기에 네트워크 디스크 https://pan.baidu.com/s/1xykIgqKUAUm_l0iVHbh6kw 추출 코드에 저장됩니다 hbvz를 

실행 샷 :

 

  

이 생각을 완료, 나는 문제가 라인에 배포 할 수 없습니다 기대하지 않았다! !

WF ?? 원래의 운영 및 유지 보수가 낮은 매우 낮은 신뢰의 C 버전이 설치된 소프트웨어의 서버 버전, 기본에 너무 의존 호환 확인하거나 이동하지 않습니다

두 가지 해결책이 있습니다 :

1 높은 GLIBC_2.14, GLIBC_2.16의 설치의 서버 버전을 확인하려면;

이 패키지는, 외부 고정 표시기 크롤링 서비스를 제공하기 위해 내부에 2 파충류 직접 시간에 요청 상기 인터페이스는, 상기 인터페이스는 마이크로 채널 페이지 비즈니스 다시 크롤링이고

이 회사는 K8S 클러스터를 가지고 있기 때문에, 직접 빌드 있도록 고정 표시기는 더 간단하게, 그래서 옵션 2를 선택

파이썬 고정 표시기 버전

, phantomjs에게 헤드리스의 현재 크롬을 운전하거나 사용하는 경우 그것은 크롤러하는 고정 표시기 점, 직접 사용 파이썬 스크립트를 사용하거나 더 많은 폭력 파이썬의 일부를 사용하는 것만 큼 간단, 직접 핍의 다양한에 따라 2017 년은 모니터링 파충류을 할 수있는 머리가없는 브라우저를 사용하여 위에 스위칭 직접 API를 변경하지

첫 번째 패키지 고정 표시기 : 차지하는 환경에서 항만 노동자를 이동하고 관련 의존을 찾아

고정 표시기 - 그것은 -v / 테스트를 실행 / 테스트 파이썬 : 3.7.4 / 빈 / bash는

  

파일 전송 고정 표시기를 촉진하기 / 공유 디렉토리로 테스트 및 호스트를 사용하여

3.7.4 직접 다운로드 뎁 설치 패키지 https://dl.google.com/linux/direct/google-chrome-stable_current_amd64.deb : 구글 크롬, 파이썬 설치

这有网盘共享 链接: https://pan.baidu.com/s/15rlArB7xCGOHXSko6UUkJA 提取码: p6d5

docker内安装google-chrome

然后就是解决依赖,

现在直接上Dockerfile

# Use an official Python runtime as a parent image
FROM python:3.7.4

# Set the working directory to /app
WORKDIR /app

# Copy the current directory contents into the container at /app
COPY . /app

#install depend
RUN apt update && apt -y --fix-broken install libnss3-dev fonts-liberation libappindicator3-1 libasound2 libatk-bridge2.0-0 libatk1.0-0 libatspi2.0-0 libcups2 libdbus-1-3 libgtk-3-0 libx11-xcb1 libxcomposite1 libxcursor1 libxdamage1 libxfixes3 libxi6 libxrandr2 libxtst6 lsb-release xdg-utils libdbusmenu-glib4 libdbusmenu-gtk3-4 libindicator3-7 libasound2-data libatk1.0-data libavahi-client3 libavahi-common3 adwaita-icon-theme libcolord2 libepoxy0 libjson-glib-1.0-0 librest-0.7-0 libsoup2.4-1 libwayland-client0 libwayland-cursor0 libwayland-egl1 libxinerama1 libxkbcommon0 libgtk-3-common libgtk-3-bin distro-info-data gtk-update-icon-cache libavahi-common-data gtk-update-icon-cache dconf-gsettings-backend libjson-glib-1.0-common libsoup-gnome2.4-1 glib-networking xkb-data dconf-service libdconf1 libproxy1v5 glib-networking-services glib-networking-common gsettings-desktop-schemas default-dbus-session-bus dbus libpam-systemd systemd systemd-sysv libapparmor1 libapparmor1 libcryptsetup12 libidn11 libip4tc0 libkmod2 libargon2-1 libdevmapper1.02.1  libjson-c3 dmsetup \
&& apt-get install -y fonts-wqy-zenhei \
&& dpkg -i google-chrome-stable_current_amd64.deb

# Install any needed packages specified in requirements.txt
RUN pip install --trusted-host pypi.python.org -r requirements.txt

d +x run.sh

# Make port 80 available to the world outside this container
EXPOSE 80

# Define environment variable
ENV NAME World

#v1 dev Run app.py when the container launches
#CMD ["python", "app.py"]
#v2 production
#CMD ["gunicorn","--config","gunicorn_config.py","app:app"]
#v3 
#ENTRYPOINT [
"gunicorn","--config","gunicorn_config.py","app:app"] #v4 ENTRYPOINT ["./run.sh"]

项目目录

app.py   处理请求

from flask import Flask
import os
import socket
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.chrome.options import Options
from selenium.webdriver.support.wait import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.common.by import By
import time
from time import sleep


app = Flask(__name__)

@app.route("/hello/<cookie_str>/<aim_url>/<end_class>")
def hello(cookie_str,aim_url,end_class):
    print(cookie_str)
    print(aim_url)
    print(end_class)
    chrome_options = Options()
    chrome_options.add_argument("--headless")
    chrome_options.add_argument("--no-sandbox")
    chrome_options.add_argument("--disable-gpu")
    chrome_options.add_argument('window-size=1200x600')
    user_ag='Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/71.0.3578.80 Safari/537.36'
    chrome_options.add_argument('user-agent=%s'%user_ag)

    profile_url = "https://work.weixin.qq.com/wework_admin/frame#profile"
    base_url = "https://work.weixin.qq.com"
    #chromedriver
    driver = webdriver.Chrome(executable_path=(r'/test/chromedriver'), chrome_options=chrome_options)

    #加载首页设置登录cookie
    driver.get(base_url + "/")
    driver.implicitly_wait(10)
    driver.save_screenshot('screen1.png')
    for coo in cookie_str.split(';'):
        cooki=coo.split('=')
        print(cooki[0].strip())
        print(cooki[1].strip())
        driver.add_cookie({'name':cooki[0].strip(),'value':cooki[1].strip(),'domain':'work.weixin.qq.com','httpOnly':False,'path':'/','secure':False})

    driver.implicitly_wait(10)

    #跳转目标页面
    driver.get(profile_url)
    WebDriverWait(driver,20,0.5).until(EC.presence_of_element_located((By.CLASS_NAME, 'ww_commonCntHead_title_inner_text')))
    #sleep(5)
    driver.save_screenshot('screen.png')

    driver.close()
    return "hhhhhh $s" % cookie_str

if __name__ == "__main__":
    app.run(host='0.0.0.0', port=80)

  

run.sh

#!/bin/bash
set -e
pwd

touch access.log error.log

exec gunicorn app:app \
        --bind 0.0.0.0:80 \
        --workers 4 \
        --timeout 120 \
        --log-level debug \
        --access-logfile=access.log \
        --error-logfile=error.log

exec "$@"

  

requirements.txt

Flask
selenium
gunicorn

  

flask的内置服务器开发的时候能用,线上部署的时候使用官方推荐的gunicorn部署,这里直接用了gunicorn运行

gunicorn的启动配置后来写进run.sh了,所以gunicorn_config.py就没用了

docker 镜像构建

docker build -t mypythonflask:v6 .

docker启动命令

docker run -d -v /data:/data -p 8888:80 -v /dev/shm:/dev/shm mypythonflask:v6

这里的/dev/shm是为了解决当加载的页面过大或者加载大图docker内存不够浏览器爆掉 解决方案来着 https://stackoverflow.com/questions/39936240/selenium-error-in-python-webdriverexception-unknown-error-session-deleted-bec/57302028#57302028

Selenium error in python: WebDriverException: unknown error: session deleted because of page crash from tab crashed

  

 请求测试

[root@localhost testdockerchrome]# curl "http://localhost:8888/hello/sss=sss;%20_ssst=1/bb/cc"
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
<title>500 Internal Server Error</title>
<h1>Internal Server Error</h1>
<p>The server encountered an internal error and was unable to complete your request. Either the server is overloaded or there is an error in the application.</p>

#处理时间太长导致超时,检查下截图

 

  

这曲折的实现历程。。。

至此,爬取服务搭建完毕,后面只要是处理一下业务相关的东西,比如拓展app.py的功能,使其支持更多的操作

总结下来就是使用docker部署了一个服务,该服务接收登录cookie,url,配置等参数,使用chrome的headless模式抓取页面操作页面,返回结果,拓展浏览器操作可以写在app.py中

 

^-^原创文章,转载请声明出处

 

추천

출처www.cnblogs.com/timseng/p/11287815.html