#python #html #web-scraping #beautifulsoup
#python #HTML #веб-очистка #прекрасный суп
Вопрос:
Как мне изменить параметры метода findAll, чтобы считывать как li, так и id? li — это элементы, а id — это правильные атрибуты?
#Author: David Owens
#File name: soupScraper.py
#Description: html scraper that takes surf reports from various websites
import csv
import requests
from bs4 import BeautifulSoup
###################### SURFLINE URL STRINGS AND TAG ###########################
slRootUrl = 'http://www.surfline.com/surf-report/'
slSunsetCliffs = 'sunset-cliffs-southern-california_4254/'
slScrippsUrl = 'scripps-southern-california_4246/'
slBlacksUrl = 'blacks-southern-california_4245/'
slCardiffUrl = 'cardiff-southern-california_4786/'
slTagText = 'observed-wave-range'
slTag = 'id'
#list of surfline URL endings
slUrls = [slSunsetCliffs, slScrippsUrl, slBlacksUrl, slCardiffUrl]
###############################################################################
#################### MAGICSEAWEED URL STRINGS AND TAG #########################
msRootUrl = 'http://magicseaweed.com/'
msSunsetCliffs = 'Sunset-Cliffs-Surf-Report/4211/'
msScrippsUrl = 'Scripps-Pier-La-Jolla-Surf-Report/296/'
msBlacksUrl = 'Torrey-Pines-Blacks-Beach-Surf-Report/295/'
msTagText = 'rating-text text-dark'
msTag = 'li'
#list of magicseaweed URL endings
msUrls = [msSunsetCliffs, msScrippsUrl, msBlacksUrl]
###############################################################################
'''
This method iterates through a list of urls and extracts the surf report from
the webpage dependent upon its tag location
rootUrl: The root url of each surf website
urlList: A list of specific urls to be appended to the root url for each
break
tag: the html tag where the actual report lives on the page
returns: a list of strings of each breaks surf report
'''
def extract_Reports(rootUrl, urlList, tag, tagText):
#empty list to hold reports
reports = []
#loop thru URLs
for url in urlList:
try:
#request page
request = requests.get(rootUrl url)
#turn into soup
soup = BeautifulSoup(request.content, 'lxml')
#get the tag where report lives
reportTag = soup.findAll(id = tagText)
for report in reportTag:
reports.append(report.string.strip())
#notify if fail
except:
print 'scrape failure'
pass
return reports
#END METHOD
slReports = extract_Reports(slRootUrl, slUrls, slTag, slTagText)
msReports = extract_Reports(msRootUrl, msUrls, msTag, msTagText)
print slReports
print msReports
На данный момент только slReports печатает правильно, потому что у меня явно установлено значение id = tagText. Я также знаю, что мой параметр тега в настоящее время не используется.
Ответ №1:
Итак, проблема в том, что вы хотите выполнить поиск в дереве синтаксического анализа элементов, которые имеют либо имя класса rating-text
(оказывается, вам не нужно text-dark
идентифицировать соответствующие элементы в случае Magicseaweed), либо идентификатор observed-wave-range
, используя один findAll
вызов.
Для достижения этой цели вы можете использовать функцию фильтра:
def reportTagFilter(tag):
return (tag.has_attr('class') and 'rating-text' in tag['class'])
or (tag.has_attr('id') and tag['id'] == 'observed-wave-range')
Затем измените свою extract_Reports
функцию на чтение:
reportTag = soup.findAll(reportTagFilter)[0]
reports.append(reportTag.text.strip())
Комментарии:
1. Куда бы эта функция фильтра вошла в код, который у меня есть в настоящее время?
2. Подождите, неважно, я понял, что reportTagFilter находится в параметре функции findAll