Python & BeautifulSoup 4/Selenium - 无法从 kicksusa.com 获取数据?

Posted

技术标签:

【中文标题】Python & BeautifulSoup 4/Selenium - 无法从 kicksusa.com 获取数据?【英文标题】:Python & BeautifulSoup 4/Selenium - Unable to get data from kicksusa.com? 【发布时间】:2019-08-01 01:16:19 【问题描述】:

我正在尝试从 kicksusa.com 抓取数据,但遇到了一些问题。

当我尝试像这样的基本 BS4 方法时(导入是从使用所有这些的主程序复制/粘贴的):

import requests
import csv
import io
import os
import re
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.chrome.options import Options
from datetime import datetime
from bs4 import BeautifulSoup

data1 = requests.get('https://www.kicksusa.com/')
soup1 = BeautifulSoup(data1.text, 'html.parser')

button = soup1.find('span', attrs='class': 'shop-btn').text.strip()
print(button)

结果是“无”,这告诉我数据是通过 JS 隐藏的。所以,我尝试使用 Selenium,如下所示:

options = Options()
options.headless = True
options.add_argument('log-level=3')
driver = webdriver.Chrome(options=options)
driver.get('https://www.kicksusa.com/') 
url = driver.find_element_by_xpath("//span[@class='shop-btn']").text
print(url)
driver.close()

我得到“无法找到元素”。

有人知道如何使用 BS4 或 Selenium 抓取该网站吗?提前谢谢!

【问题讨论】:

您的 selenium 代码是正确的,并且适用于 Firefox 驱动程序。 print(driver.find_element_by_xpath("//span[@class='shop-btn']").text) 使用 Firefox 驱动程序输出“Shop Puma”。也许这是无头镀铬的问题?您还应该尝试在getfind_element_by_xpath 之间超时。 您实际需要哪些数据?只是像shop puma之​​类的文字?还是您打算点击按钮? @nmb.ten - 这很奇怪,同样的代码适用于另一个 URL/网站上的 Chrome 驱动程序。我会尝试添加超时,谢谢您的输入。 @QHarr - 我只是想获取文本,上面的 sn-p 只是我尝试获取任何数据时的一个例子(我在 a.hrefs 的 div 类之后)项目”在这个exact URL 上——然后我会将hrefs 提供给一个循环,打开它们并获取品牌和型号) 【参考方案1】:

问题是您被检测为机器人并得到如下响应:

<html style="height:100%">
    <head>
        <META NAME="ROBOTS" CONTENT="NOINDEX, NOFOLLOW">
        <meta name="format-detection" content="telephone=no">
        <meta name="viewport" content="initial-scale=1.0">
        <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
        <script type="text/javascript" src="/_Incapsula_Resource?SWJIYLWA=719d34d31c8e3a6e6fffd425f7e032f3"></script>
    </head>
    <body style="margin:0px;height:100%">
    <iframe src="/_Incapsula_Resource?CWUDNSAI=20&xinfo=5-36224256-0%200NNN%20RT%281552245394179%20277%29%20q%280%20-1%20-1%200%29%20r%280%20-1%29%20B15%2811%2c110765%2c0%29%20U2&incident_id=314001710050302156-195663432827669173&edet=15&cinfo=0b000000"
            frameborder=0   margin margin>Request unsuccessful. Incapsula
        incident ID: 314001710050302156-195663432827669173
    </iframe>
    </body>
</html>

请求和 BeautifulSoup

如果您想使用requestsbs,请从浏览器开发工具中复制visid_incap_incap_ses_ cookie 从请求标头到www.kicksusa.com 并在您的request 中使用它们:

import requests
from bs4 import BeautifulSoup

headers = 
    'Host': 'www.kicksusa.com',
    'Connection': 'keep-alive',
    'Cache-Control': 'max-age=0',
    'Upgrade-Insecure-Requests': '1',
    'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_2) AppleWebKit/537.36 (KHTML, like Gecko) '
                  'Chrome/72.0.3626.121 Safari/537.36',
    'DNT': '1',
    'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8',
    'Accept-Encoding': 'gzip, deflate, br',
    'Accept-Language': 'ru,en-US;q=0.9,en;q=0.8,tr;q=0.7',
    'Cookie': 'visid_incap_...=put here your visid_incap_ value; incap_ses_...=put here your incap_ses_ value',


response = requests.get('https://www.kicksusa.com/', headers=headers)

page = BeautifulSoup(response.content, "html.parser")

shop_buttons = page.select("span.shop-btn")
for button in shop_buttons:
    print(button.text)

print("the end")

当您运行 Selenium 有时时,您会得到相同的响应:

重新加载页面对我有用。试试下面的代码:

from selenium import webdriver

driver = webdriver.Chrome()
driver.get('https://www.kicksusa.com/')

if len(driver.find_elements_by_css_selector("[name=ROBOTS]")) > 0:
    driver.get('https://www.kicksusa.com/')

shop_buttons = driver.find_elements_by_css_selector("span.shop-btn")
for button in shop_buttons:
    print(button.text)

【讨论】:

非常感谢您的详细回复。结果,BS4 方法仍然给我“无”(我很肯定我正确放置了 visid_incap 和 incap_ses 值)。即使在摆弄它以获得我所追求的确切数据之后,Selenium 方法似乎也运行良好。如果您能在回复的第一部分解释如何找到回复,我将不胜感激,因为我将来可以自己解决类似的情况。 @kamen1111 我在 chrome 私有窗口中获得了 init_incap 值。值如下所示:init_incap_40678=.... @kamen1111 我也不知道他们有没有超时。您也可以使用 Selenium 打开页面,只是为了从缓存中获取初始值,然后使用请求进行进一步解析。【参考方案2】:

对于您想要重复的链接,您可以使用以下 css 选择器限制每对中的第一个

#products-grid .item [href]:first-child

.find_elements_by_css_selector("#products-grid .item [href]:first-child")

【讨论】:

谢谢 - 这对于我需要编写的另一个程序肯定很有用,但我相信在这种情况下有一些机器人检测在起作用。 data1 = requests.get('https://www.kicksusa.com/mens-shoes.htm') 中的 requests.get 没有提取它应该提取的数据。【参考方案3】:

请尝试以下代码。它应该会返回按钮的文本。希望对您有所帮助。

from selenium import webdriver
options = webdriver.ChromeOptions()
options.add_argument('--headless')
options.add_argument("--start-maximized")
options.add_argument('--disable-browser-side-navigation')
options.add_argument('window-size=1920x1080');
driver = webdriver.Chrome(chrome_options=options)
driver.get('https://www.kicksusa.com/')
url = driver.find_element_by_css_selector("span.shop-btn")
print(driver.execute_script("return arguments[0].innerHTML", url))

【讨论】:

感谢您的帮助,但这仍然返回selenium.common.exceptions.NoSuchElementException: Message: no such element: Unable to locate element: "method":"css selector","selector":"span.shop-btn" 奇怪。我可以看到按钮文本。你复制的正是我写的内容 我确保我复制了准确​​的代码,但仍然出现错误。

以上是关于Python & BeautifulSoup 4/Selenium - 无法从 kicksusa.com 获取数据?的主要内容,如果未能解决你的问题,请参考以下文章

python安装Django需要环境

如何使用python从网站中提取所有链接[重复]

python网络爬虫 - 如何伪装逃过反爬虫程序

beautifulsoup模块

beautifulsoup模块

Beautifulsoup模块