【发布时间】:2021-03-11 04:57:10
【问题描述】:
我是一个新手,正在尝试组合我的第一个网页抓取功能,并且遇到了一些我不完全理解的 HTTP 问题。作为参考,我正在尝试从FanGraphs ZIPS projection page 抓取。
他们的页面默认显示包含 30 名玩家的牌桌,但您可以编辑网页,使牌桌每页显示 10、20、30、50、100、500 或 1000 个结果。理想情况下,我会选择每页 500 个结果的选项,但是当我更改下拉菜单时,URL 保持不变,所以我尝试编写一个脚本来获取 HTML 代码并在尝试请求之前编辑 HTML 页面的属性网页的那个变体。 (如果查看页面源代码,则在第 1247 行)
或者,您可以使用页面上的箭头按钮超链接循环浏览其他页面,但它们也不会更改 URL。
我为位置玩家解决了这个问题,因为我可以单独抓取每个位置,然后连接单独的 Pandas 数据帧,但我对 HTTP 请求的工作原理完全不了解,希望得到一些帮助/指导。
我尝试了类似的方法:
from requests import Request, Session
url = 'https://www.fangraphs.com/projections.aspx?pos=all&stats=pit&type=zips&team=0&lg=al&players=0'
page = requests.get(url)
soup=BeautifulSoup(page.text, 'html.parser')
resultSet = soup.findAll(value=30)
for result in resultSet:
result["value"]="500"
s = Session()
req = requests.Request('POST', url, data = {'ProjectionBoard1_dg1_ctl00_ctl03_ctl01_PageSizeComboBox_Input value': 500})
resp = s.send(prepped)
print(resp.status_code)
我的想法是抓取结构,编辑配置以匹配我想要的网页,然后反刍固定结构以抓取数据。然后我意识到我不知道自己在做什么。
有几点: 我在这里“甚至没有错”吗?这是否可能与请求或我需要像 Selenium 这样的东西?我是否不正确地使用 POST?
旁注:如果上下文有帮助,对于位置球员我这样做了(对投手也会做同样的事情):
base_url = 'https://www.fangraphs.com/projections.aspx?pos=&stats=bat&type=zips&team=0&lg=all&players=0'
positions = ['c', '1b', '2b', '3b', 'ss', 'lf', 'cf', 'rf']
def generate_positional_urls(urlRoot=base_url, pos=positions):
index = base_url.index('pos=') + 4 position after
urlList = []
numPositions = len(positions)
for i in range(numPositions):
position = pos[i]
tempURL = urlRoot[:index] + position + urlRoot[index:]
urlList.append(tempURL)
return urlList
其中的内容:
def generate_df(url):
page = urlopen(url)
soup = BeautifulSoup(page, 'html.parser')
masterTable = soup.findAll('table', {"class": "rgMasterTable"}, {"id": "ProjectionBoard1_dg1_ct100"})
table_rows = masterTable[0].find_all('tr')
data = []
for tr in table_rows:
td = tr.find_all('td')
row = [tr.text for tr in td]
data.append(row)
headers = masterTable[0].find_all("thead")
colElements = headers[0].find_all("tr")
soupColResults = colElements[1].findChildren("a")
colStrings = [element.text for element in soupColResults]
df = pd.DataFrame(data)
df.columns = colStrings
df.drop(columns=[''], inplace=True)
df = df.iloc[3:, :]
return df
那么循环和连接数据帧就很容易了,但是对于这个HTTP问题,我真的不知道我在做什么。
注意:我这样做是为了尝试学习和练习 Python。我可以通过使用我的网络浏览器单击超链接将数据导出到 csv 来轻松避免这种情况,因此不必费力找出不必要的乏味。
【问题讨论】: