无法使用BS4从eastbay.com抓取数据?

时间:2019-04-17 18:12:04

标签: python selenium web-scraping beautifulsoup

所以我选择了我感兴趣的品牌,并生成了该URL:

https://www.eastbay.com/category/mens/shoes.html?query=%3Arelevance%3Agender%3A200000%3AproductType%3A200005%3Abrand%3AChampion%3Abrand%3AConverse%3Abrand%3AFila%3Abrand%3AJordan%3Abrand%3ANew+Balance%3Abrand%3ANike%3Abrand%3ANike+SB%3Abrand%3APUMA%3Abrand%3AReebok%3Abrand%3ASalomon%3Abrand%3AThe+North+Face%3Abrand%3ATimberland%3Abrand%3AUGG%3Abrand%3AUnder+Armour%3Abrand%3AVans%3Abrand%3Aadidas%3Abrand%3Aadidas+Originals&

我正在尝试从此页面抓取数据,主要是产品页面URL(href类的元素a的{​​{1}}属性值)。

我的第一个问题是,使用BS4,我无法从网站上获取任何数据。

即使运行了这个简单的测试代码段(不管大多数导入,它们都在主程序中使用了),

Link--product

应在类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 headers = { 'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_13_6) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36', } data = requests.get("https://www.eastbay.com/category/sport/casual/mens/shoes.html",headers=headers) soup = BeautifulSoup(data.text, 'lxml') x = soup.find('span', attrs={'class': 'primary'}).text.strip() print(x) 中打印第一个span元素中的文本(结果应为primary),并返回错误Nike Air Force 1 Low,该错误应指示我的标题未被主机接受,但是我尝试了许多不同的标头,但均未成功。

我使用以下简单的代码片段使Selenium发挥作用并显示requests.exceptions.ConnectionError: ('Connection aborted.', OSError("(10060, 'WSAETIMEDOUT')"))

Nike Air Force 1 Low

但如果可能的话,我真的更喜欢使用BS4。有谁知道如何使BS4与该网站一起工作?

我的第二个问题是关于此网站上的分页。 URL底部附近有一个“加载更多”按钮,该按钮向API发出请求,然后加载下一批产品。但是,URL永远不会改变。谁能帮我遍历这些批次,以便可以获取所有产品,而不仅仅是前60个?

我尝试了类似的方法,从另一个网站的脚本修改而来,该脚本在URL中也没有分页:

driver = webdriver.Chrome()
driver.get("https://www.eastbay.com/category/sport/casual/mens/shoes.html") 
x = driver.find_element_by_xpath("//span[@class='primary']")
print(x.text)
driver.close()

但是这将导致一个空列表或卡住。

我已经检查了Chrome Dev工具中“网络”标签中的“ XHR和获取”标签,可以看到单击“加载更多”按钮发出的请求类型,但是对于传递查询字符串我一无所知参数来迭代产品批次。

非常感谢您的帮助。

1 个答案:

答案 0 :(得分:1)

您对XHR的想法正确。这是获取方法,然后遍历json格式以打印出所需的输出:

import requests

url = 'https://www.eastbay.com/api/products/search'

headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.103 Safari/537.36'}

payload = {
'query': ':relevance:sport:Casual:gender:200000:productType:200005',
'currentPage': '1',
'pageSize': '200',
'timestamp': '4'}

jsonData = requests.get(url, headers=headers, params=payload).json()

totalPages = jsonData['pagination']['totalPages']
totalResults = jsonData['pagination']['totalResults']

print ('%s total results to aquire' %totalResults)


for page in range(1,totalPages+1):
    payload = {
            'query': ':relevance:sport:Casual:gender:200000:productType:200005',
            'currentPage': page,
            'pageSize': '200',
            'timestamp': '4'}


    jsonData = requests.get(url, headers=headers, params=payload).json()

    try:
        for product in jsonData['products']:
            print (product['name'])
    except:
        print ('Products not found on this request')