在这种情况下,如何从正则表达式中提取数据?

时间:2019-04-22 03:01:06

标签: python regex web-scraping

我正在尝试从this URL抓取车手姓名

当前,我正为正则表达式表达式而苦苦挣扎,因为它可以很好地匹配内容(regex101),但是我不确定如何获取匹配的正则表达式并使用它来提取多少值。

当我抓取时,我可以将findall更改为finditer以与之匹配(并接收结果),但是我不确定如何去那里,并反复获取返回值到列表中的方法

# import modules
import urllib.request
import urllib.parse
import re

# fake user agent for access
user_agent = 'Mozilla/5.0 (Windows; U; Windows NT 5.1; en-US; rv:1.9.0.7) Gecko/2009021910 Firefox/3.0.7'
headers={'User-Agent':user_agent,}

url = 'https://dataride.uci.ch/Results/iframe/RankingDetails/119?disciplineId=8&groupId=48&momentId=39994&disciplineSeasonId=139&rankingTypeId=1&categoryId=22&raceTypeId=71'
req = urllib.request.Request(url, None,headers)
resp = urllib.request.urlopen(req)
respData = resp.read()

riders = re.findall(r'(<a)\s+(href=\"/Results/iframe/RiderRankingDetails/)[0-9]+(\?rankingId=)[0-9]+(\&amp;groupId=)[0-9]+(\&amp;momentId=)[0-9]+(\&amp;baseRankingTypeId=)[0-9]+(\&amp;disciplineSeasonId=)[0-9]+(\&amp;disciplineId=)[0-9]+(\&amp;categoryId=)[0-9]+(\&amp;raceTypeId=)[0-9]+(\">)[A-Z]+\s+[A-Za-z]+(</a>),str(respData))
# The [A-Z]+\s+[A-Za-z] part contains the rider name that I wish to scrape

for name in riders:
    print(name)
regex表达式中的

[A-Z]+\s+[A-Za-z]应该返回给列表骑手,以便我可以打印出每个骑手的姓名。

3 个答案:

答案 0 :(得分:0)

正如评论中提到的@DYZ一样,该网页是动态生成的,当您尝试使用urlib下载该网页时,您将获得如下所示的网页: NonSenseWebpage

但是,如果您通过浏览器访问同一网页,则会显示所有骑手和排名,因为浏览器执行Java脚本,而urllib或请求这样的下载器则不执行

the webpage via browser

如果您需要本网站的信息,则应该寻求另一种方法,或者,如果您只想学习网页抓取,可以尝试beautifulSoup

答案 1 :(得分:0)

很明显,要捕获的元素是动态生成的。因此,您需要selenium。从您的描述中,您想要获得车手的名字。首先,您必须下载与Chrome版本匹配的chromedriver。然后尝试以下代码:

from selenium import webdriver
from selenium.webdriver.common.keys import Keys

browser = webdriver.Chrome(r'/path/chromedriver')  #refers to the path of your downloaded chromedriver

browser.get("https://dataride.uci.ch/Results/iframe/RankingDetails/119?disciplineId=8&groupId=48&momentId=39994&disciplineSeasonId=139&rankingTypeId=1&categoryId=22&raceTypeId=71")

post_elems = browser.find_elements_by_tag_name("a")

for post in post_elems[3:]:
    if post.text != '':
        print (post.text)

输出:

CORNEGLIANI Fabrizio
BACHMAIER Ernst
JAHODA Patrik
FRÜH Benjamin
SIMEONI Manolo
TUOR Alain
UBERTI Giuseppe
GOMIERO Andrea
PANTANO Dino

答案 2 :(得分:0)

您可以模仿页面的POST请求,该请求比使用浏览器要快

import requests

headers = {'User-Agent' : 'Mozilla/5.0',
           'Referer' : 'https://dataride.uci.ch/Results/iframe/RankingDetails/119?disciplineId=8&groupId=48&momentId=39994&disciplineSeasonId=139&rankingTypeId=1&categoryId=22&raceTypeId=71'}
data = {

'rankingId' : 119,
'disciplineId' : 8,
'currentRankingTypeId' : 1,
'rankingTypeId' : 1,
'take' : 40,
'skip' : 0,
'page' : 1,
'pageSize' : 40,
'filter[filters][0][field]' : 'RaceTypeId',
'filter[filters][0][value]' : 71,
'filter[filters][1][field]' : 'CategoryId',
'filter[filters][1][value]' : 22,
'filter[filters][2][field]' : 'SeasonId',
'filter[filters][2][value]' : 139,
'filter[filters][4][value]' : 0 
}
r = requests.post('https://dataride.uci.ch/Results/iframe/ObjectRankings/', headers = headers, data = data).json()   
riders = [item['DisplayName'] for item in r['data']]
print(riders)

输出:

enter image description here