【问题标题】:Why does socket interfere with selenium?为什么套接字会干扰硒?
【发布时间】:2020-05-26 10:34:16
【问题描述】:

我编写了一个 python 脚本来使用套接字 (Checking network connection) 检查互联网连接,然后使用 selenium 从 yahoo Finance 抓取 html。

非常频繁(但并非总是),它会给出 ReadTimeoutError(见下文)

我可以通过使用 http.client 检查互联网连接来让它工作(见下文),但我仍然想知道为什么套接字会干扰 selenium。


def internet(host="8.8.8.8", port=443, timeout=1):
    try:
        socket.setdefaulttimeout(timeout)
        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        s.connect((host, port))
        s.shutdown(socket.SHUT_RDWR)
        s.close()
        return True
    except OSError:  
        s.close()
        return False

#  Wait for internet to be available

i = 1
while internet() is False:
    time.sleep(1)
    if i == 300:  # quit if no connection for 5 min (300 seconds)
        print('\nIt has been 5 minutes. Aborting attempt.\n')
        sys.exit(0)
    i += 1

# Get html from yahoo page

symb = 'AAPL'
url = 'http://finance.yahoo.com/quote/{}/history'.format(symb)

chop = webdriver.ChromeOptions()
chop.add_argument('--user-agent="Mozilla/5.0 (Macintosh; Intel Mac OS X 10.14; rv:68.0) Gecko/20100101 Firefox/68.0"')
driver = webdriver.Chrome('/Users/fake_user/Dropbox/Python/chromedriver', chrome_options=chop)
driver.get(url)
html_source = driver.page_source
driver.quit()

它会抛出这个错误:

urllib3.exceptions.ReadTimeoutError: HTTPConnectionPool(host='127.0.0.1', port=58956):读取超时。 (读取超时=)

我可以更改互联网功能作为解决方法,但我无法弄清楚为什么套接字会干扰硒:

import http.client as httplib

def internet():
    conn = httplib.HTTPConnection("www.google.com", timeout=5)
    try:
        conn.request("HEAD", "/")
        conn.close()
        return True
    except:
        conn.close()
        return False

【问题讨论】:

  • 这里有同样的问题。我认为问题在于 socket.setdefaulttimeout() 是一个全局套接字设置。

标签: python selenium sockets selenium-webdriver


【解决方案1】:

来自documentation

socket.setdefaulttimeout(超时)

为新的套接字对象设置默认超时时间(以秒为单位)。首次导入 socket 模块时,默认值为 None。请参阅 settimeout() 了解可能的值及其各自的含义。

问题在于setdefaulttimeout 为所有新创建的套接字设置了超时,因此也为 Selenium 设置了超时。这是一个全局套接字库设置。

如果您只想对此套接字实例使用超时,请使用socket.settimeout(value) (doc)。

def internet(host="8.8.8.8", port=443, timeout=1):
try:
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    s.settimeout(timeout) # correction from s.timeout(timeout)
    s.connect((host, port))
    s.shutdown(socket.SHUT_RDWR)
    s.close()
    return True
except OSError:  
    s.close()
    return False

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-11-11
    • 1970-01-01
    • 2018-12-26
    • 1970-01-01
    • 1970-01-01
    • 2022-01-05
    • 2011-11-22
    • 1970-01-01
    相关资源
    最近更新 更多