多彩な投稿サイト[python+selenium]

50566 ワード

ターゲットWebサイト
遭遇した穴
このサイトは反爬虫のために多くの戦略を使用していますが、これらの戦略は爬虫類の中で遭遇する可能性のある穴です.
目的:このページのこの状態の項目(projectStatus=6)を這い出すことを目的とする(終了した旨を示すと推定される)
ピット1
  • ピット:上の図示のページでは、具体的な項目のページリンクを直接取得できません.ページのアドレスは動的にロードされます.つまり,各項目への具体的なリンクを直接取得することはできない.
  • 解決方法:これは私の後で1つの方法(selenium)で一緒に解決されましたが、実はseleniumを使う必要はありません.しかし、この問題だけなら、network関連のリクエストをバックグラウンドで見ることができる一方で、jsのプロセスを見ることができます.

  • ピット2
  • ピット:各プロジェクトページで、特定の情報ページにロードされます.jsがページを自動的に置き換える技術を採用しています.同じように、seleniumを使って
  • を実現したいと思っています.
  • 解決策:seleniumダイナミックシミュレーション
  • ピット3
  • ピット:特定のデータページにおけるデータの変換.例えば、少し後ろのページについて話していると、ページのデータの内容が変わっています.
  • 例えば、最高投げ可能なものもあれば、一人当たり制限投げられるものもあります.実は本質的に同じ意味です.
  • " ", " "も同じ理屈
  • " ", " "
  • そして最初のデータ表示では、真ん中は(中国語入力法の)ですが、後ろに:(英語入力法のコロンにスペースを付けて区切り文字として)
  • というページもあります
  • 解決策:すべて中国語で文字列の代替を行います.

  • ピット4
  • ピット:最初のデータは各行で表されていましたが、その後、ある2つのデータにランダムに直接、(改行文字で区切られている)が使用されることがわかりました.このように,一般的にpタグを直接取得するとバグが発生する.データがキャプチャされない場所があります.
  • 解決策:次のコードセグメントです.具体的なhtmlコードを取得し、htmlの構造に基づいて分析します.隠れた穴!!(find_…なんていうのは、存在しないと誤報になります.でも前に言ったのはこれがランダムなので…tryでしか実現できません)
  • tempDatas = []
            for d in datas:
                try:
                    td = d.find_element_by_tag_name('span').get_attribute("innerHTML")
                    if '
    '
    in td: tds = td.split('
    '
    ) for tdi in tds: tempDatas.append(tdi.replace('
    '
    , '').replace(' ', ' ').replace(': ', ':').replace(':', ":").strip()) else: tempDatas.append(d.text.strip().replace('
    '
    , '').replace(': ', ':').replace(':', ":")) except Exception as e: tempDatas.append(d.text.strip().replace('
    '
    , '').replace(': ', ':').replace(':', ":")) datas = tempDatas

    ピット5
  • ピット:ページ構造が変化しました.以前のデータは少し近いデータとは違うようです.例えば、私たちが望んでいるデータの位置についてspan.以前は1つ目でしたが、後ろの方で2つ目の上にいることもあるので、情報がなかなか登れない場合があります.
  • 解決策:ここの解決策は実はまだ十分ではありませんが、少なくとも十分です.最後の1つを使います.以前は1つのspanしかなかった場合、それは同じですが、2つのspanがある場合、データは一般的に後ろのspanの中にあります.だから私は[-1]のような方法でインデックスを行いました.

  • ピット6
  • ピット:毎回手動でログインします.非常に面倒です.ここには検証コードが必要です.そして、検証コードは手動で何かをスライドさせてから、携帯電話に送る必要があります.そして、送信後、携帯番号は1日5回しか送信できません.これはとても穴があいている.
  • 解決策:pickleを使用してcookiesを格納します.そして毎回1回だけ呼び出して、後で、ログインページにアクセスしてcookiesをロードすればいいです.私の実験によると、各cookiesは1日使用できます.そして、向こうのこのサイトは、このcookiesをリフレッシュします.

  • 具体的なコードクリップ:
  • refreshは、cookies
  • をリフレッシュするか否かを示す.
    if refresh:
        browser.get(LOGIN_URL)
        #   
        time.sleep(2)
        input = browser.find_element_by_xpath('//input[@placeholder="      "]')
        input.send_keys(USERNAME)
        time.sleep(40)
        pickle.dump(browser.get_cookies(), open("cookies.pkl", "wb"))
        print('finish refresh')
        browser.get(tempURL)  #     
        time.sleep(2)
    else:
        browser.get(LOGIN_URL)  #     
        cookies = pickle.load(open("cookies.pkl", "rb"))
        for cookie in cookies:
            browser.add_cookie(cookie)
        browser.get(tempURL)  #     
        time.sleep(2)
    

    ピット7
  • ピット:一部はプロジェクトの価値があり、一部はプロジェクト会社の価値があり、一部は両者がこれを持っていることに驚いた.
  • 解決方法:辞書で保存したいので、あれば追加します.そうしないとNULLを追加します.

  • ピット8
  • ピット:このページは不思議ですが(サーバーの品質が悪いかもしれません)、ページのデータのロード速度が遅い場合があります.(ロードの遅延が高い).時には、具体的なデータを取得したが、対応する会社の名前には登っていないことがある.これは仕方がない.
  • 解決策:会社名が空の場合は再ロードするように設定します.その後、最大一定の再ロード回数です.

  • 似たようなWebページの切り替えがある場合も失敗しますが、リフレッシュすればいいです.これは私が制限して、一定の回数になったら直接プログラム全体を終了します.なぜなら、ある晩登って取りましたが、夜中にネットが切れて...空のデータをずっと登っていることに気づきました.だからこんなデザインがありました.
    同時に、私も待機メカニズムを増やしました.次のようなものです.
    elemnt = WebDriverWait(browser, 10).until(
                    EC.presence_of_element_located(
                        (By.XPATH, '//*[@id="__layout"]/div/div[2]/div/div[3]/ul/li[%d]/div/div/div[1]/div[2]/h3' % (
                                index_i + 1)))
                )
    

    同じ停電のため、私は前に多くの役に立つデータを登ったが、保存していなかったので、途中で一定回数記録したコードを入れた.突然の問題を避けるために、中間のデータを維持します.
    ピット9
  • 古いデータになると、データがないことに気づき、すべて画像でデータを表す
  • これは私の解決していない問題です:画像の中で...私は300本以上の少しきれいなデータを登ったので、十分だと思います.
  • は画像内にデータを埋め込み、これは画像文字抽出の技術しかできない.

  • コードの使用方法
  • pageCount第数ページ(最初の画像で示す)
  • index_iは、数ページ目の数(0からカウント)
  • である.
    これを使用してセグメントを作成できます(問題が発生した場合、一部の部分ではこれを使用して再起動を設定できます)
  • refresh = FalseがTrueの場合、手動で登録する必要があります.そして、リフレッシュが完了するのを待ってからcookiesが保存されていることを示します.あとで再起動するときは、Falseに設定します.これでもうログインする必要はありません.
  • configureという部分のコードは、一般の人が注釈する必要があります.私はこのコードを持っています.主に私のchromeがソースコードで置き換えられたからです.だからシステムに書き込んでいません.そして、実行ファイルのアドレスを手動で書きます.普通の人はこのコードを必要としません.コメントを忘れないで!!!
  • ダウンロードして必要なライブラリ~
  • あとはそのまま運転すればいいです.長い間使っていました.
    完全なコード
    from selenium import webdriver
    from selenium.webdriver.common.by import By
    from selenium.webdriver.support.ui import WebDriverWait
    from selenium.webdriver.support import expected_conditions as EC
    import time
    import pickle
    import pandas as pd
    
    #####################
    USERNAME = "        "
    #             url       
    URL = "https://www.duocaitou.com/project?projectStatus=6&pageNum=%d"
    pageCount = 1
    tempURL = URL % pageCount
    LOGIN_URL = "https://www.duocaitou.com/login?redirect=%2Fproject"
    refresh = False
    
    #####################
    # configure
    options = webdriver.ChromeOptions()
    options.binary_location = r"D:\Software\Chrome\Application\chrome.exe"
    browser = webdriver.Chrome(chrome_options=options)
    
    keys = ['    ', '      ', '    ', '    ', '    ', '    ', '    ', '    ']
    globalData = {}
    for k in keys:
        globalData[k] = []
    
    if refresh:
        browser.get(LOGIN_URL)
        #   
        time.sleep(2)
        input = browser.find_element_by_xpath('//input[@placeholder="      "]')
        input.send_keys(USERNAME)
        time.sleep(40)
        pickle.dump(browser.get_cookies(), open("cookies.pkl", "wb"))
        print('finish refresh')
        browser.get(tempURL)  #     
        time.sleep(2)
    else:
        browser.get(LOGIN_URL)  #     
        cookies = pickle.load(open("cookies.pkl", "rb"))
        for cookie in cookies:
            browser.add_cookie(cookie)
        browser.get(tempURL)  #     
        time.sleep(2)
    
    print(tempURL)
    save = 0
    times = 0
    
    index_i = 0
    continuetime = 0
    
    try:
        while True:
            try:
                elemnt = WebDriverWait(browser, 10).until(
                    EC.presence_of_element_located(
                        (By.XPATH, '//*[@id="__layout"]/div/div[2]/div/div[3]/ul/li[%d]/div/div/div[1]/div[2]/h3' % (
                                index_i + 1)))
                )
                li_list = browser.find_element_by_xpath(
                    '//*[@id="__layout"]/div/div[2]/div/div[3]/ul/li[%d]/div/div/div[1]/div[2]/h3' % (index_i + 1)).click()
                elemnt = WebDriverWait(browser, 10).until(
                    EC.presence_of_element_located(
                        (By.XPATH, '//*[@id="__layout"]/div/div[2]/div/div[1]/div[1]/div[2]/div[1]/div/div/div/div/div[3]'))
                )
                browser.find_element_by_xpath(
                    '//*[@id="__layout"]/div/div[2]/div/div[1]/div[1]/div[2]/div[1]/div/div/div/div/div[3]').click()
    
                elemnt = WebDriverWait(browser, 10).until(
                    EC.presence_of_element_located(
                        (By.XPATH, '//*[@id="__layout"]/div/div[2]/div/div[1]/div[1]/div[2]/div[2]/div[2]/div/span'))
                )
                datas = browser.find_elements_by_xpath(
                    '//*[@id="__layout"]/div/div[2]/div/div[1]/div[1]/div[2]/div[2]/div[2]/div/span')
    
                if "    " in datas[0].text:
                    datas = datas[0]
                else:
                    datas = datas[-1]
                elemnt = WebDriverWait(datas, 10).until(
                    EC.presence_of_element_located(
                        (By.TAG_NAME, 'p'))
                )
                time.sleep(5 + continuetime)
                datas = datas.find_elements_by_tag_name('p')[0:40]
            except Exception as e:
                browser.get(tempURL)  #     
                print('refresh', tempURL, 'index is', index_i)
                time.sleep(5)
    
                continuetime += 1
                if continuetime >= 10:
                    break
                continue
            datas = [d for d in datas if len(d.text.strip()) > 4 and (':' in d.text or ':' in d.text)][:8]
    
            tempDatas = []
            for d in datas:
                try:
                    td = d.find_element_by_tag_name('span').get_attribute("innerHTML")
                    if '
    '
    in td: tds = td.split('
    '
    ) for tdi in tds: tempDatas.append(tdi.replace('
    '
    , '').replace(' ', ' ').replace(': ', ':').replace(':', ":").strip()) else: tempDatas.append(d.text.strip().replace('
    '
    , '').replace(': ', ':').replace(':', ":")) except Exception as e: tempDatas.append(d.text.strip().replace('
    '
    , '').replace(': ', ':').replace(':', ":")) datas = tempDatas try: tempdict = {} for d in datas: if ':' not in d: continue a = d[:d.index(':')] b = d[d.index(':') + 1:] if a == ' ': a = ' ' a = a.replace(" ", " ").replace(" ", " ") if a in tempdict: if ' :' in b: b = b.split(' :') tempdict[' '] = b[0] tempdict[' '] = b[1] else: tempdict[' '] = b elif a == ' ' and ' :' in b: b = b.split(' :') tempdict[a] = b[0] tempdict[' '] = b[1] elif a == ' ' and ' :' in b: b = b.split(' :') tempdict[' '] = b[0] tempdict[' '] = b[1] else: tempdict[a] = b if len(tempdict) == 0 or ' ' not in tempdict: continuetime += 1 if continuetime < 3: browser.get(tempURL) # time.sleep(2) continue else: continuetime = 0 for key in globalData.keys(): if key in tempdict: globalData[key].append(tempdict[key]) elif key == ' ': globalData[' '].append(tempdict[key]) elif key == ' ': globalData[' '].append(tempdict[key]) else: globalData[key].append('NULL') print(key, ': ', globalData[key][-1], end=' , ') print() times += 1 if times % 50 == 49: pd.DataFrame(globalData).to_excel('data_%d.xlsx' % save, columns=keys) save += 1 times = 0 except Exception as e: print(e.args) for i, d in enumerate(datas): print(i, d) break if index_i == 8: index_i = 0 pageCount += 1 if pageCount >= 67: break tempURL = URL % pageCount print(tempURL) browser.get(tempURL) # time.sleep(2) else: browser.get(tempURL) # time.sleep(2) index_i += 1 continuetime = 0 finally: pd.DataFrame(globalData).to_excel('data.xlsx', columns=keys)