标签 selenium 下的文章

目的

不登录,爬取tuniu网站部分页面数据

问题

python操作selenium,直接打开具体页面,页面为空,无内容

无内容原因:

  1. tuniu 采用了阿里云的前端安全验证 https://g.alicdn.com/sd/ncpc/nc.js
  2. cookie 关键值是 acw_sc__v3

解决办法:

  1. 使用未被收录特征的工具 利用google浏览器 打开 tuniu 首页
  2. 使用未被收录特征的工具 利用google浏览器 通过 tuniu 首页的h5的拖拽验证码 的验证,则此时浏览器会缓存一定有效期的 acw_sc__v3 cookie
  3. 在cookie默认有效期内,执行selenium相关代码(options.add_argument(user_data_dir)),这样selenium就不会被要求安全验证了。

解决办法

logger.info('点击下翻月份')
xiayiye = self.browser.find_element_by_xpath(
    '//div[@class="mp-direct mp-direct-next" and @mp-role="nextMonthBtn" and @style="display: block;"]/a')
# 点击
# xiayiye.click()  # Message: element not interactable
self.browser.execute_script(
    "arguments[0].click();", xiayiye)

  1. 本地安装好python3以及相应模块
  2. 本地安装好谷歌浏览器
  3. 本地下载好配套谷歌浏览器的chromedriver
  4. 代码范例: 
    #!/usr/bin/python3.6

    from selenium import webdriver
    import shutil
    import os
    import sys
    import time
    import json
    import msvcrt
    import random

    # 设置用户输入的input超时
    def readInput(caption, default, timeout=10):
        start_time = time.time()
        sys.stdout.write('%s(%d秒未输入取默认值):' % (caption, timeout))
        sys.stdout.flush()
        input = ''
        while True:
            ini = msvcrt.kbhit()
            try:
                if ini:
                    chr = msvcrt.getche()
                    if ord(chr) == 13:  # enter_key
                        break
                    elif ord(chr) >= 32:
                        input += chr.decode()
            except Exception as e:
                print(str(e))
            if len(input) == 0 and time.time() - start_time > timeout:
                break
        print('')  # needed to move to next line
        if len(input) > 0:
            return input+''
        else:
            return default


    class selenium_class:
        executable_path = 'D:\\chromedriver.exe'
        chrome_options = webdriver.ChromeOptions()
        chrome_options.add_argument(
            "user-agent='Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/60.0.3112.78 Safari/537.36'")
        prefs = {'profile.default_content_settings.popups': 0}
        chrome_options.add_experimental_option('prefs', prefs)
        cookies_file_path = os.path.join(os.path.split(os.path.realpath(__file__))[
            0], 'cookies.txt')
        # print(cookies_file_path)

        def __init__(self, login_url, fresh_url):
            self.loginUrl = login_url
            self.freshUrl = fresh_url
            self.browser = webdriver.Chrome(
                executable_path=self.executable_path, chrome_options=self.chrome_options)
            self.browser.set_page_load_timeout(10)
            self.browser.set_script_timeout(10)

        def write_cookies(self):
            self.browser.get(self.freshUrl)
            cookies = self.browser.get_cookies()
            with open(self.cookies_file_path, "w") as fp:
                fp.write(json.dumps(cookies))

        def read_cookies(self):
            with open(self.cookies_file_path, "r", encoding='utf-8') as fp:
                cookies = json.load(fp)
                list_cookies = []
                for cookie in cookies:
                    self.browser.add_cookie(cookie)
                    list_cookies.extend(cookie)
                print(list_cookies)

        def login(self):
            print('跳转登录界面')
            self.browser.get(self.loginUrl)
            print('请输入登录用户名和密码,如果不输入,则跳转手动登录')
            self.username = readInput("请输入登录用户名:", '')
            self.password = readInput("请输入登录密码:", '')
            if self.username and self.password:
                print('自动填写输入的用户名和密码,并进行登录')
                self.browser.find_element_by_xpath(
                    '//*[@id="input_username"]').send_keys('username')  # 输入用户名
                self.browser.find_element_by_xpath(
                    '//*[@id="input_password"]').send_keys('password')  # 输入密码
                self.browser.find_element_by_xpath(
                    '//*[@id="input_go"]').click()  # 点击登陆
            else:
                print('执行sleep,请手动登录')
                time.sleep(30)
            print('将cookies写入文件')
            self.write_cookies()
            print('写入完毕')

        def fresh(self):
            print('从文件中读取cookies')
            self.read_cookies()
            print('读取完毕')
            print('跳转刷屏页面')
            self.browser.get(self.freshUrl)
            time.sleep(8)

        def logout(self):
            print('退出browser')
            self.browser.quit()
            print('退出程序')


    if __name__ == "__main__":
        try:
            loginUrl = 'http://jiankong.ykzp.com/login'
            freshUrl = 'http://jiankong.ykzp.com/webstats/'
            instance = selenium_class(loginUrl, freshUrl)
            instance.login()
            instance.fresh()
            for num in range(1, 10000):
                print('执行第'+str(num)+'次刷屏')
                instance.browser.find_element_by_xpath(
                    '//*[@id="J_chatContent"]').send_keys('刷屏内容')
                instance.browser.find_element_by_xpath(
                    '/html/body/nav/a').click()
                time.sleep(random.randint(4, 15))
        except Exception as e:
            print(e, e.__traceback__.tb_lineno)
        finally:
            instance.logout()
            os.remove(instance.cookies_file_path)