python - 无法使用 BS4 从eastbay.com 抓取数据?
问题描述
所以我选择了我感兴趣的品牌,并生成了这个 URL:
我正在尝试从此页面中抓取数据,主要是产品页面 URL(具有类的元素的href
属性值)。a
Link--product
我的第一个问题是,使用 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
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
),返回错误requests.exceptions.ConnectionError: ('Connection aborted.', OSError("(10060, 'WSAETIMEDOUT')"))
,这应该表明我的标题没有被主机接受,但是我尝试了许多不同的标题但没有成功。
我Nike Air Force 1 Low
使用这个简单的代码片段让 Selenium 工作和显示:
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()
但如果可能的话,我真的更喜欢使用 BS4。有谁知道如何让 BS4 与这个网站一起工作?
我的第二个问题是关于这个网站的分页。在 URL 的底部附近,有一个“加载更多”按钮,该按钮向 API 发出请求,然后加载下一批产品。但是,URL 永远不会改变。谁能帮我迭代批次以便获取所有产品,而不仅仅是前 60 个产品?
我尝试了这样的方法,从另一个网站的脚本修改,该脚本在 URL 中也没有分页:
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"
qsp = {
'currentPage': 1,
'pageSize': 100,
'timestamp': 3
}
container = []
for page_content in range(0,1500,60):
qsp['currentPage'] = page_content
res = requests.get(url,params=qsp,headers={"User-Agent":"Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/73.0.3683.86 Safari/537.36"})
soup = BeautifulSoup(res.text, 'lxml')
for item in soup.select(".c-product-card a"):
container.append("https://www.eastbay.com"+item['href'])
for items in soup.select("script"):
sauce = BeautifulSoup(items.text,"lxml")
for elem in sauce.select(".c-product-card a"):
container.append("https://www.eastbay.com"+elem['href'])
print(container)
但这会导致一个空列表或只是卡住。
我已经检查了 Chrome 开发工具中网络选项卡中的 XHR 和 Fetch 选项卡,我可以看到单击“加载更多”按钮正在发出什么样的请求,但是在传递查询字符串参数以进行迭代时我一无所知超过批次产品。
任何帮助深表感谢。
解决方案
你对 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')
推荐阅读
- angular - 我想安装 angular-cli 时遇到问题
- apache-kafka - Kafka:高可用性所需的最少代理数量是多少?
- reactjs - Reactjs 访问另一个组件的状态
- mongodb - MongoDB。选择其他网络中存在的字段
- php - 选择计数字符串,然后将它们分组到饼图
- android - Google Play 服务错误任务“:transformClassesWithJarMergingForRelease”执行失败
- javascript - 更改 axios 请求网络名称
- typescript - 在 Typescript 中获取和设置?
- python - Flask SQLAlchemy 查询 beetwen 2 个表
- c# - 根据选择的不同 ComboBoxItem 值自动选择 ComboBoxItem