21 KiB
Komputerowe wspomaganie tłumaczenia
9,10. Web scraping [laboratoria]
Rafał Jaworski (2021)
Jak dobrze wiemy, w procesie wspomagania tłumaczenia oraz w zagadnieniach przetwarzania języka naturalnego ogromną rolę pełnią zasoby lingwistyczne. Należą do nich korpusy równoległe (pamięci tłumaczeń), korpusy jednojęzyczne oraz słowniki. Bywa, że zasoby te nie są dostępne dla języka, nad którym chcemy pracować.
W tej sytuacji jest jeszcze dla nas ratunek - możemy skorzystać z zasobów dostępnych publicznie w Internecie. Na dzisiejszych zajęciach przećwiczymy techniki pobierania tekstu ze stron internetowych.
Poniższy kod służy do ściągnięcia zawartości strony (w formacie HTML do zmiennej) oraz do wyszukania na tej stronie konkretnych elementów. Przed jego uruchomieniem należy zainstalować moduł BeautifulSoup:
pip3 install beautifulsoup4
import requests
from bs4 import BeautifulSoup
url='https://epoznan.pl'
page = requests.get(url)
soup = BeautifulSoup(page.content, 'html.parser')
headers = soup.find_all('h3', {'class':'postItem__title'})
print('\n'.join([header.get_text() for header in headers]))
W Poznaniu uroczyście odsłonięto monument upamiętniający cmentarz żydowski założony jeszcze w XIX wieku Przez ulice Poznania przejdzie Marsz dla Życia. Będą utrudnienia Sierść psa zatopiona w żywicy? Taką biżuterię pamiątkową zlecają właściciele czworonożnych pociech Nagrał film w jednej z poznańskich "Biedronek". Kilka spleśniałych cytryn w kartonie. "Nikt się tym nie przejmuje" Gniezno: poszkodowani po ulewie będą mogli ubiegać się o pomoc w ZUS i US. Powstała również specjalna infolinia Zostawiła jedzenie dla potrzebujących. Coraz więcej głodnych osób, którym nie wystarcza pieniędzy po opłaceniu rachunków Kolejne ostrzeżenie I stopnia od IMGW. Oprócz burz może wystąpić również grad Lech przegrał Koroną. Na trybunach marsz żałobny i 'mamy k**** dość' Warta Poznań po przegranej z Jagielonią Białystok spada do I ligi Mieszkańcy skarżą się na właściciela samochodu, w którym notorycznie włącza się alarm. "Uprzykrza nam to życie!" Leśne Placówki Montessori Na autostradzie samochód wpadł w poślizg i stanął w poprzek. Są spore utrudnienia Wróciła plaga kradzieży katalizatorów. Zmora dla kierowców, którzy nie mogą garażować auta Nowy basen w Kiekrzu? W tunelu wody przybyło po same kolana Pierożki Dim Sum z Para Bar Rataje ze specjalną zniżką! Wielka głowa Darii Zawiałow zablokowała przez chwilę przejście dla pieszych na jednej z poznańskich ulic Fałszywy pożar w centrum Poznania. Kłęby dymu w kamienicy? Jest kolejne ostrzeżenie pierwszego stopnia, tym razem hydrologiczne. Gwałtowny wzrost stanu wody Uwaga. Utrudnienia na drodze i ograniczenie prędkości. Potrwa to około 5 godzin Chcą pobić rekord w kręceniu lodów. Tona lodów w ciągu doby Jest ostrzeżenie IMGW dla Wielkopolski. Lepiej schować przedmioty, które mogą przemieścić się pod wypływem silnego wiatru Nowe Centrum Medyczne Bizpark już w sprzedaży. Znajdź idealny lokal pod swoją działalność medyczną Rondo Obornickie: zderzenie samochodu z motocyklem. Poszkodowany został odwieziony do szpitala. Chwilowe utrudnienia Policjanci publikują wizerunek i szukają tego mężczyzny Grupa Stonewall będzie miała program na antenie TVP3 Poznań. "To będzie odtrutka na lata dezinformacji" Ruszył remont ważnego mostu. Co z kłódkami zakochanych? Mieszkaniec spotkał wilka w Poznaniu? Włamanie do... lokomotywy W nadwarciański krajobraz wpisały się... żurawie. "Jeden jest największy na świecie" Robisz remont? Za to możesz słono zapłacić!
Ćwiczenie 1: Napisz funkcję do pobierania nazw towarów z serwisu Ceneo.pl. Typ towaru, np. telewizor, pralka, laptop jest parametrem funkcji. Wystarczy pobierać dane z pierwszej strony wyników wyszukiwania.
from bs4 import element
def get_names(article_type, page_nr: int = 0):
url = 'https://www.ceneo.pl/;szukaj-' + article_type + ';0020-30-0-0-' + str(page_nr) + '.htm'
page = requests.get(url)
if page_nr != 0 and url != page.url:
return []
soup = BeautifulSoup(page.content, 'html.parser')
result = []
def is_product_title_container(tag: element.Tag) -> bool:
if not tag.has_attr('class'):
return False
classes = tag.attrs['class']
if len(classes) != 1:
return False
return classes[0] == 'cat-prod-row__name'
def is_product_title(tag: element.Tag) -> bool:
if not tag.has_attr('class'):
return True
classes = tag.attrs['class']
if len(classes) != 1:
return False
return classes[0] == 'font-bold'
for tag in soup.find_all(is_product_title_container):
href = tag.find('a')
if type(href) is not element.Tag:
continue
spans = href.find_all('span')
for span in spans:
if is_product_title(span):
result.append(span.text)
return result
W ten sposób pobieramy dane z jednej strony. Nic jednak nie stoi nam na przeszkodzie, aby zasymulować przełączanie stron.
Ćwiczenie 2: Zaobserwuj, jak zmienia się url strony podczas przechodzenia do kolejnych stron wyników wyszukiwania na Ceneo.pl. Wykorzystaj tę informację i uruchom funkcję get_names() na więcej niż jednej stronie wyników.
def scrape_names():
result = []
search = 'laptop'
page = 0
while True:
local_result = get_names(search, page)
if len(local_result) == 0:
return result
result = result + local_result
page += 1
Technika pobierania treści z Internetu jest szczególnie efektywnym sposobem na pozyskiwanie dużych ilości tekstu. Poniższy fragment kodu służy do ściągnięcia całości tekstu ze strony.
import re
url = "https://www.yahoo.com"
page = requests.get(url)
soup = BeautifulSoup(page.content, 'html.parser')
# usunięcie elementów script i style
for script in soup(["script", "style"]):
script.extract() # usuń element
# pobierz tekst
text = soup.get_text()
# usuń wielokrotne białe znaki
text = re.sub(r"\s+", " ", text)
print(text)
Yahoo Make Yahoo Your HomepageDiscover something new every day from News, Sports, Finance, Entertainment and more! HOME MAIL NEWS FINANCE SPORTS ENTERTAINMENT LIFE SHOPPING YAHOO PLUS MORE... Download the Yahoo Home app Yahoo Home Search query Sign in Mail Sign in to view your mail Mail Mail COVID-19 COVID-19 News News Finance Finance Sports Sports Entertainment Entertainment Life Life Shopping Shopping Yahoo Plus Yahoo Plus More... More... Follow live:Closing arguments begin for Derek Chauvin's murder trial in the death of George Floyd 5 people in hospital after shooting in Louisiana One victim was shot in the head, and another suffered multiple gunshot wounds, according to local news outlet.Multiple police units dispatched to scene »2 dead in crash of Tesla with 'no one' drivingMall shooter, 16, faces 1st-degree murder charge'80s pop star rips 'Simpsons' for 'hateful' parodyConspiracy theorist Alex Jones faces a reckoningPig's head left at former home of Chauvin trial witness U.S.HuffPostFirst-Ever Wild Wolf Collar Camera Shows What They Really Do All Day LongThis canine's favorite meal might surprise you. Thanks for your feedback! CelebrityThe TelegraphRobert De Niro unable to turn down acting roles because of his ‘estranged wife's expensive lifestyle’Hollywood legend Robert De Niro is unable to turn down acting roles because he must pay for his estranged wife's expensive tastes, the actor's lawyer has claimed. Caroline Krauss told a Manhattan court that he is struggling financially because of the pandemic, a massive tax bill and the demands of Grace Hightower, who filed for divorce in 2018 after 21 years of marriage. The court has been asked to settle how much De Niro should pay Ms Hightower, 66, until the terms of the prenuptial agreement the couple negotiated in 2004 takes effect. “Mr De Niro is 77 years old, and while he loves his craft, he should not be forced to work at this prodigious pace because he has to,” Ms Krauss told the court. “When does that stop? When does he get the opportunity to not take every project that comes along and not work six-day weeks, 12-hour days so he can keep pace with Ms Hightower’s thirst for Stella McCartney?” Thanks for your feedback! U.S.Associated PressCouple: Man has tossed used cups in their yard for 3 yearsAn upstate New York couple may have finally solved the mystery of who's been tossing used coffee cups in their front yard for nearly three years. Edward and Cheryl Patton told The Buffalo News they tried mounting a camera in a tree in front of their home in Lake View to catch the phantom litterer. After Edward Patton called police, they waited and pulled over a vehicle driven by 76-year-old Larry Pope, who Cheryl Patton said had once worked with her and had had disagreements with her over union issues. Thanks for your feedback! U.S.INSIDERA leading conspiracy theorist who thought COVID-19 was a hoax died from the virus after hosting illegal house partiesA high-profile conspiracy theorist from Norway, who shared false information about the pandemic online, has died from COVID-19, officials say. Thanks for your feedback! PoliticsThe WeekOne America News Network producer says 'majority' of employees didn't believe reports on voter fraud claimsMarty Golingan, a producer at One America News Network, a right-wing cable news channel often noted for its affinity for former President Donald Trump, told The New York Times he was worried his work may have helped inspire the Jan. 6 Capitol riot. At one point during the incident, Golingan said he caught sight of someone in the mob holding a flag with OAN's logo. "I was like, OK, that's not good. That's what happens when people listen to us," he told the Times, referring to OAN's coverage of the 2020 presidential election, which often gave credence to Trump's unfounded claims of widespread voter fraud and Democratic conspiracies. Golingan said that many of his colleagues, including himself, disagreed with the coverage. "The majority of people did not believe the voter fraud claims being run on the air," he told the Times. Indeed, the Times interviewed 18 current and former OAN employees, 16 of whom said the channel has "broadcast reports that they considered misleading, inaccurate, or untrue." But Allysia Britton, a former producer and one of more than a dozen employees to leave OAN in the wake of the riot, explained that while "many people have raised concerns ... when people speak up about anything, you will get in trouble." Read more at The New York Times. More stories from theweek.comThe new HBO show you won't be able to stop watchingDonald Trump's most dangerous political legacyTrump's NSA general counsel Michael Ellis resigns, never having taken office Thanks for your feedback! BusinessMoneyWiseFourth stimulus check update: Biden faces mounting pressure for new paymentAdvocates and lawmakers say the crisis isn't over, and neither is the need for relief. Thanks for your feedback! CelebrityThe TelegraphLand Rover driver at Prince Philip's funeral spent week ensuring he could drive at correct speedHuffPostPrince Philip's Funeral, In PhotosUSA TODAY EntertainmentWhy did Prince Philip's Land Rover carry his casket? The story behind the strange hearse Thanks for your feedback! Trending Now1. Gianna Hammer2. Derek Chauvin3. Black Rob4. 2021 Acm Awards5. Baby Shower Invitations6. Amanda Broderick7. Mortgage Refinance Calculator8. Interest Rates Today9. Tesla Crash10. Mars Helicopter Yahoo! Mail WeatherWeatherGreater PolandView your LocationsRemove from favorite locationsDetect my locationEnter City or ZipcodeManage LocationsToday66°45°TueRain today with a high of 59 °F (15.0 °C) and a low of 41 °F (5.0 °C). There is a 50% chance of precipitation.59°41°WedPartly cloudy today with a high of 57 °F (13.9 °C) and a low of 41 °F (5.0 °C).57°41°ThuScattered showers today with a high of 48 °F (8.9 °C) and a low of 37 °F (2.8 °C). There is a 35% chance of precipitation.48°37°See More » ScoreboardChange Sports to display different scoresNBA NFL MLB NHL NCAAB NCAAF Trending YesterdayTodayTomorrowPortland Charlotte 101109FinalSacramento Dallas 121107FinalMinnesota LA Clippers 105124FinalMore scores » HoroscopeChange your horoscope signAriesTaurusGeminiCancerLeoVirgoLibraScorpioSagittariusCapricornAquariusPiscesApril 19 -Aries - You're feeling the heat, and you may find that your friends like it as much as you do! Your great energy is perfect for almost any activity, so light up the night and have a great time! See more » Yahoo! Mail Yahoo! Sports Terms (Updated)Privacy (Updated)AdvertiseAbout Our AdsCareersHelpFeedback Close this content, you can also use the Escape key at anytime
Ćwiczenie 3: Napisz program do pobrania tekstu ze strony Wydziału Matematyki i Informatyki. Pobierz cały tekst ze strony głównej a następnie wyszukaj na tej stronie wszystkich linków wewnętrznych i pobierz tekst ze stron wskazywanych przez te linki. Nie zagłębiaj się już dalej.
def scrape_wmi():
def get_text(soup_l: BeautifulSoup) -> str:
for trash in soup_l(['script', 'style']):
trash.extract()
text = soup_l.get_text()
return re.sub(r'\s+', ' ', text)
result = []
base_url = 'https://wmi.amu.edu.pl/'
page = requests.get(base_url)
soup = BeautifulSoup(page.content, 'html.parser')
result.append(get_text(soup))
for href in soup.find_all('a'):
if type(href) != element.Tag:
continue
if not href.has_attr('href'):
continue
if base_url in href.attrs['href']:
sub_page = requests.get(href.attrs['href'])
result.append(get_text(BeautifulSoup(sub_page.content, 'html.parser')))
return result
Omówione wyżej techniki działają również bardzo dobrze dla zasobów słownikowych.
Ćwiczenie 4: Pobierz jak najwięcej słów w języku albańskim z serwisu glosbe.com.
Nie jest to rozwiązanie zbalansowane, ale pobierze najwięcej słów (Przy odpowiedniej rotacji adresów IP, z których korzystamy, ale założyłem, że kwestia infrastruktury i tego jak strona jest chroniona przed atakami DOS, jest poza zakresem tego zadania)
def scrape_shqip():
import string
result = []
letters = list(string.ascii_lowercase)
letters_count = len(letters)
longest_sensible_english_word_len = 28
base_url = 'https://glosbe.com/en/sq/'
def get_words(word_l: str) -> list[str]:
def is_translated_word(tag: element.Tag) -> bool:
if not tag.has_attr('id') or not tag.has_attr('lang'):
return False
if not 'translation__' in tag.attrs['id'] or 'sq' != tag.attrs['lang']:
return False
return True
result_l = []
page = requests.get(base_url + word_l)
soup = BeautifulSoup(page.content, 'html.parser')
words_l = soup.find_all(is_translated_word)
for word_l in words_l:
text = word_l.text
result_l.append(re.sub(r'\s+', ' ', text))
return result_l
def trans(word_l: list[int]) -> str:
result_l = ''
for letter_l in word_l:
result_l += letters[letter_l]
return result_l
def increment(word_l: list[int]) -> list[int]:
done = False
result_l = []
for letter_l in word_l:
if done:
result_l.append(letter_l)
continue
next_letter_l = letter_l + 1
if next_letter_l == letters_count:
result_l.append(0)
continue
result_l.append(next_letter_l)
done = True
return result_l
for length in range(longest_sensible_english_word_len - 1):
length += 1
combos = pow(length, letters_count)
word = []
for pos in range(length):
word.append(0)
for i in range(combos):
result.append(get_words(trans(word)))
word = increment(word)
return result