刮网站,为什么代码会给出不同的结果?

时间:2018-06-15 22:26:13

标签: python python-3.x web-scraping

为什么当我点击网站并查看网站源代码时,它会给我一个有组织的结果。

我想要的只是日期,球队和得分。

这是我的Python代码:

import requests, bs4
from bs4 import BeautifulSoup
r=requests.get("https://www.scoreboard.com/mls/results/")
soup=bs4.BeautifulSoup(r.content,"lxml")
print(soup.prettify())

这是我搜索洛杉矶"时的结果。我的代码返回了:

enter image description here

但是当我打开网站的源代码时:https://www.scoreboard.com/mls/results/ 它告诉我:

enter image description here

我不知道为什么Python结果完全不同。

2 个答案:

答案 0 :(得分:0)

requests.get(url)

此代码会向网址发布http请求,网站服务器会返回网站源代码。如果您点击Chrome中的CTRL + U,则源代码将与您的python抓取结果相同。

你问的不同结果是网站加载后会加载数据,它将由网站的javascript加载。换句话说,您想要的数据是由Ajax加载的。

您可以打开Chrome - > F12 - > Network - > XHR - >刷新你的网站想要刮。

请注意Chrome的日志。您可以通过这种方式获得Ajax数据。有时您应该转换格式。

与您的网站一样,我找到两个地址来获取Ajax数据:

  • https://www.scoreboard.com/x/feed/mc_8

  • https://d.scoreboard.com/x/feed/tr_1_200_CQv5qrFt_155_1_8_en-usa_1

但你需要做一些事情,比如根据相应的js代码转换格式。

答案 1 :(得分:0)

这个站点使用自己的feed语法,似乎它们使用〜作为行分隔符,¬表示对象分隔符,÷表示键/值。以下是:

  

SA÷1¬〜ZA÷USA:   MLS¬ZEE÷÷CQv5qrFt¬ZB÷200¬ZY÷USA¬ZC÷zRdKgb4m¬ZD÷t¬ZE÷KM2qHMND¬ZF÷0¬ZO÷0¬ZG÷1¬ZH÷200_CQv5qrFt¬ZJ÷2¬ZL/毫升/¬ZX÷04USA   003 ...... 0000000000179000MLS 003 ......000¬ZS÷2018ZZ÷0¬ZAF÷USA-~AA÷bTyQbGCR-AD÷1528943400-÷1528943400¬AB÷3¬CR÷3¬ AC÷÷3¬CX圣   何塞地震-RW÷0¬AX÷1¬BX÷-1¬HMC÷1WW÷¬WM÷JOS-AE÷圣何塞   Earthquakes¬JA÷÷Ms72iE3l¬WUSAN何塞 - earthquakes¬AS÷÷0¬AZ÷0¬AG÷2¬BA÷1¬BC÷1¬WN÷ENG¬AF新   英国   Revolution¬JB÷G466jYIf¬WV÷新英格兰-revolution¬AS÷0¬AZ÷0¬AH÷2¬BB÷2¬BD÷0¬AW÷1¬

以json格式变为此(JSON对象在此处表示单行):

{
    "SA" : "1",
},
{
    "ZA": "USA : MLS",
    "ZEE": "CQv5qrFt",
    "ZB": "200",
    "ZY": "USA",
    "ZC": "zRdKgb4m",
    "ZD": "t",
    "ZE": "KM2qHMND",
    "ZF": "0",
    "ZO": "0",
    "ZG": "1",
    "ZH": "200_CQv5qrFt",
    "ZJ": "2",
    "ZL": "/mls/",
    "ZX": "04USA         003......0000000000179000MLS         003......000",
    "ZS": "2018",
    "ZCC": "0",
    "ZAF": "USA"
}

如果你看https://www.scoreboard.com/x/js/core_500_1495000000.js它包含缩小的代码,只需将eval替换为console.log来打印整个代码并找到关键名称,如ZEE,ZA,ZD等。 ..你会想出这样的东西:

{
    "sportId" : "1",
},
{
    "tournamentName": "USA : MLS",
    "tournamentTemplateId": "CQv5qrFt",
    "countryId": "200",
    "countryName": "USA",
    "tournamentStageId": "zRdKgb4m",
    "tournamentType": "t",
    "tournamentId": "KM2qHMND",
    "sourceType": "0",
    "hasLiveTable": "0",
    "statsType": "1",
    "tournamentTemplateKey": "200_CQv5qrFt",
    "tournamentStageType": "2",
    "tournamentTemplateUrl": "/mls/",
    "sortKey": "04USA         003......0000000000179000MLS         003......000",
    "seasonUrl": "2018",
    "stagesCount": "0",
    "categoryCaption": "USA"
}

这是锦标赛的描述,以下行描述了表格中的所有项目,例如一行:

{
    "eventId": "GOSl9rMa",
    "matchStartUtime": "1528938000",
    "eventStartUtime": "1528938000",
    "eventStageTypeId": "3",
    "eventStageTypeFromEventStageId": "3",
    "eventStageId": "3",
    "sortParticipant": "Colorado Rapids",
    "cricketVisibleRunRate": "0",
    "hasLineups": "1",
    "gameTime": "-1",
    "hasMatchComments": "1",
    "cricketRecentOvers": "",
    "home3CharName": "COL",
    "homeParticipantName": "Colorado Rapids",
    "eventParticipantId": "2BPTi8xM",
    "participantNameUrl": "colorado-rapids",
    "winner": "0",
    "ftWinner": "0",
    "homeCurrentResult": "2",
    "homeResultPeriod1": "2",
    "homeResultPeriod2": "0",
    "away3CharName": "CHI",
    "awayParticipantName": "Chicago Fire",
    "awayParticipantId": "t2OXjSiS",
    "awayParticipantNameUrl": "chicago-fire",
    "winner": "0",
    "ftWinner": "0",
    "awayRedCardCount": "1",
    "awayCurrentResult": "2",
    "awayResultPeriod1": "2",
    "awayResultPeriod2": "0",
    "hasLiveCenter": "1"
}

请注意,此格式中可以存在多个相同的键(在这种情况下与json不严格类比)