Я новичок в Python и в целом.В этом коде я использую как Bs4, так и Selenium.Я использую Selenium, чтобы автоматически нажимать кнопку «Показать больше», чтобы можно было просмотреть все результаты, а не только те, которые были найдены на первой странице показанных результатов.Я пытаюсь очистить следующий веб-сайт: https://boards.euw.leagueoflegends.com/en/search?query=improve
Однако при объединении Bs4 и Selenium 3 поля, которые я собираю (имя пользователя, сервер и тема), теперь дают мне следующие две ошибки.
1) Я получаю AttributeError: у объекта 'NoneType' нет атрибута 'text' для сервера и имени пользователя
Traceback (most recent call last):
File "failoriginale.py", line 153, in <module>
main()
File "failoriginale.py", line 132, in main
song_data = get_songs(index_page) # Get songs with metadata
File "failoriginale.py", line 81, in get_songs
username = row.find(class_='username').text.strip()
AttributeError: 'NoneType' object has no attribute 'text'
2) Я получаю эту ошибку с темой
Traceback (most recent call last):
File "failoriginale.py", line 153, in <module>
main()
File "failoriginale.py", line 132, in main
song_data = get_songs(index_page) # Get songs with metadata
File "failoriginale.py", line 86, in get_songs
topic = row.find('div', {'class':'discussion-footer byline opaque'}).find_all('a')[1].text.strip()
IndexError: list index out of range
Однако, прежде чем объединить bs4 с Selenium, эти 3 поля работали так же, как и другие, поэтому я думаю, что проблема в другом.Я не понимаю, в чем проблема в основной функции с song_data?Я уже посмотрел другие вопросы по stackoverflow, но не смог решить проблему.Я новичок в чистке и bs4, библиотеках селена, извините, если задаю глупый вопрос.
Вот код:
browser = webdriver.Firefox(executable_path='./geckodriver')
browser.get('https://boards.euw.leagueoflegends.com/en/search?query=improve&content_type=discussion')
html = browser.page_source #page_source is where selenium stores the html source
def get_songs(url):
html = browser.page_source
index_page = BeautifulSoup(html,'lxml') # Parse the page
items = index_page.find(id='search-results') # Get the list on from the webpage
if not items: # If the webpage does not contain the list, we should exit
print('Something went wrong!', file=sys.stderr)
sys.exit()
data = list()
# button show more, if the page has the show more button, it will click on that x5secs
if index_page.find('a', {"class": "box show-more",}):
button = browser.find_element_by_class_name('box.show-more')
timeout = time.time() + 5
while True:
button.click()
time.sleep(5.25)
if time.time() > timeout:
break
html = browser.page_source
index_page = BeautifulSoup(html,'lxml')
items = index_page.find(id='search-results')
for row in items.find_all(class_='discussion-list-item'):
username = row.find(class_='username').text.strip()
question = row.find(class_='title-span').text.strip()
sentence = row.find('span')['title']
serverzone = row.find(class_='realm').text.strip()
#print(serverzone)
topic = row.find('div', {'class':'discussion-footer byline opaque'}).find_all('a')[1].text.strip()
#print(topic)
date=row.find(class_='timeago').get('title')
#print(date)
views = row.find(class_='view-counts byline').find('span', {'class' : 'number opaque'}).get('data-short-number')
comments = row.find(class_='num-comments byline').find('span', {'class' : 'number opaque'}).get('data-short-number')
# Store the data in a dictionary, and add that to our list
data.append({
'username': username,
'topic':topic,
'question':question,
'sentence':sentence,
'server':serverzone,
'date':date,
'number_of_comments':comments,
'number_of_views':views
})
return data
def get_song_info(url):
browser.get(url)
html2 = browser.page_source
song_page = BeautifulSoup(html2, features="lxml")
interesting_html= song_page.find('div', {'class' : 'list'})
if not interesting_html: # Check if an article tag was found, not all pages have one
print('No information availible for song at {}'.format(url), file=sys.stderr)
return {}
answer = interesting_html.find('span', {'class' : 'high-quality markdown'}).find('p').text.strip() #.find('span', {"class": "high-quality markdown",}).find('p')
return {'answer': answer} # Return the data of interest
def main():
index_page = BeautifulSoup(html,'lxml')
song_data = get_songs(index_page) # Get songs with metadata
#for each row in the improve page enter the link and extract the data
for row in song_data:
print('Scraping info on {}.'.format(row['link'])) # Might be useful for debugging
url = row['link'] #defines that the url is the column link in the csv file
song_info = get_song_info(url) # Get lyrics and credits for this song, if available
for key, value in song_info.items():
row[key] = value # Add the new data to our dictionary
with open('results.csv', 'w', encoding='utf-8') as f: # Open a csv file for writing
fieldnames=['link','username','topic','question','sentence','server','date','number_of_comments','number_of_views','answer'] # These are the values we want to store
Спасибо за вашу помощь!