Как извлечь данные из выражения регулярного выражения в этом экземпляре?

#python #regex #web-scraping

#python #регулярное выражение #веб-очистка

Вопрос:

Я пытаюсь очистить имена пользователей из этого 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=8amp;groupId=48amp;momentId=39994amp;disciplineSeasonId=139amp;rankingTypeId=1amp;categoryId=22amp;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;amp;groupId=)[0-9] (amp;amp;momentId=)[0-9] (amp;amp;baseRankingTypeId=)[0-9] (amp;amp;disciplineSeasonId=)[0-9] (amp;amp;disciplineId=)[0-9] (amp;amp;categoryId=)[0-9] (amp;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)
  

[A-Z] s [A-Za-z] в выражении регулярных выражений должны быть возвращены гонщики списка, чтобы затем я мог напечатать имя каждого гонщика.

Комментарии:

1. Зачем вам нужно регулярное выражение, если вы можете очистить имена райдеров непосредственно на основе класса тегов?

2. Можете ли вы включить рабочую версию своего кода? У вас есть SyntaxError и TypeError.

3. Это потому, что он пока не выдает выходные данные, вот с чем мне нужна помощь, однако у меня, конечно, нет синтаксической ошибки. Где ошибка типа (nvm нашел ее, я думаю, это был 3-й параметр в findall, я забыл вставить его в stack overflow)? Если бы я мог просто использовать класс тегов, что мне нужно изменить? Я знаю только регулярное выражение, поскольку это то, что мне было поручено использовать здесь.

4. Страница генерируется динамически. Вы не можете загрузить его с помощью urllib. Рассмотрите возможность использования selenium или другого безголового браузера.

Ответ №1:

Как упоминал @DYZ в комментариях, веб-страница генерируется динамически, при попытке загрузить ее с помощью urlib вы получите такую веб-страницу: Бессмысленная веб-страница

но если вы посетите ту же веб-страницу через браузер, у вас будут отображаться все участники и ранги, потому что браузеры выполняют java-скрипты, которые загрузчики, такие как urllib или requests, не выполняют

веб-страница через браузер

вам следует искать другой метод, если вам нужна информация с этого сайта, или вы можете попробовать BeautifulSoup, если вы просто хотите научиться веб-очистке

Ответ №2:

Понятно, что элементы, которые вы хотите захватить, генерируются динамически. Таким образом, вам нужно selenium . Из вашего описания вы хотите получить имя гонщиков. Во-первых, вы должны загрузить chromedriver, который соответствует версии вашего Chrome. Затем попробуйте этот код:

 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=8amp;groupId=48amp;momentId=39994amp;disciplineSeasonId=139amp;rankingTypeId=1amp;categoryId=22amp;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
  

Ответ №3:

Вы можете имитировать POST-запрос страницы, что быстрее, чем при использовании браузера

 import requests

headers = {'User-Agent' : 'Mozilla/5.0',
           'Referer' : 'https://dataride.uci.ch/Results/iframe/RankingDetails/119?disciplineId=8amp;groupId=48amp;momentId=39994amp;disciplineSeasonId=139amp;rankingTypeId=1amp;categoryId=22amp;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)
  

Вывод:

введите описание изображения здесь