带有无头 chromedriver 的 Selenium 无法抓取网络数据?

blu*_*ast 2 python selenium beautifulsoup web-scraping selenium-chromedriver

我编写了一个简单的程序来从https://stats.nba.com抓取数据。我这里的代码工作得非常好,因为它能够完美地从网站获取数据:

chrome_options = webdriver.ChromeOptions()
d = webdriver.Chrome(ChromeDriverManager().install(),options=chrome_options)
d.get('https://stats.nba.com/teams/advanced/?sort=W&dir=-1')
scrape = BeautifulSoup(d.page_source, 'html.parser').find('table')

for row in scrape.find_all('tr'):
    for col in row.find_all('td'):
    #...more parsing code here
Run Code Online (Sandbox Code Playgroud)

然而,一旦我添加 chrome_options.add_argument('--headless'),整个代码就会失败并且我得到了AttributeError: 'NoneType' object has no attribute 'find_all'

为什么会出现这种情况?我到处都找过了,但找不到解决方案。谢谢!

编辑:问题似乎是d.page_source为无头和非无头给出了不同的结果。有谁知道为什么会有差异?

bor*_*hev 9

编辑:

我想我已经找到了解决方案。看来他们有一个检查浏览器用户代理的系统,并且不允许使用无头浏览器

所以尝试将其添加到您的代码中:

# ...
user_agent = 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/83.0.4103.116 Safari/537.36'
chrome_options.add_argument(f'user-agent={user_agent}')
# ... 

Run Code Online (Sandbox Code Playgroud)

这是我从中收到的输出:

scrape = BeautifulSoup(d.page_source, 'html.parser').find('table')
for row in scrape.find_all('tr'):
    print(row)
Run Code Online (Sandbox Code Playgroud)
# <tr>
# <th></th>
# <th cf="" class="text" data-field="TEAM_NAME" ripple="" sort=""><br/>TEAM</th>
# <th cf="" data-dir="-1" data-field="GP" data-rank="" ripple="" sort="">GP</th>
# <th cf="" class="sorted asc" data-dir="-1" data-field="W" data-rank="" ripple="" sort="">W</th>
# <th cf="" data-dir="-1" data-field="L" data-rank="" ripple="" sort="">L</th>
Run Code Online (Sandbox Code Playgroud)

  • 非常感谢您提供这个解决方案。我已经被这个问题困扰了很长一段时间,并且处于发疯的边缘。 (2认同)