如何使用python

时间:2019-10-22 19:06:43

标签: python html web-scraping beautifulsoup

我正在制作一本字典,该字典在西班牙语中查找单词并提供相应的英语翻译。我是BeautifulSoup的新手,所以我借此机会学习网络抓取。

该网页链接为https://www.spanishdict.com/translate/rojo。 我只是以'rojo'为例。

但是,在成功提取翻译后,我也想提取一些例句,但是在这里我遇到了一个问题。我不能在没有类名的情况下提取<span>中的其中一个句子。

我尝试了

soup.find_all(name='div', class_='indent--FyTYr')

但是该类中出现了许多不必要的信息。 我还注意到帖子the link中提到了previous_sibling的一个答案,但这没有用。

示例html代码如下所示:

<div class="indent--FyTYr">
  <div>
    <span>The sky turned red at sundown.</span>
    <span class="dash--SIa20"></span>
    <em class="exampleDesktop--3n1hN">El cielo se tornó rojo al atardecer.</em> 
  </div>
...
</div>

我想从上面的html示例代码中提取句子。但是我没有找到任何有用的方法来定位和提取。

  

日落时天空变成红色。

谢谢您的帮助。

3 个答案:

答案 0 :(得分:0)

如果您确定span将是第一个,则只需使用.find("span")

>>> soup.find_all(name='div', class_='indent--FyTYr')[0].find("span").text
'The sky turned red at sundown.'

答案 1 :(得分:0)

您可以使用递归函数遍历SO_LINGER的最外部div,以说明存在多个嵌套id='dictionary-neodict-es'且类为div的事实:< / p>

indent--FyTYr

现在,您可以使用所有句子:

from bs4 import BeautifulSoup as soup
import requests, bs4
def has_class(d, c):
   return any(c in i.attrs.get('class', []) or has_class(getattr(i, 'contents', []), c) for i in d if i != '\n' and not isinstance(i, bs4.NavigableString))

def get_sentences(d):
   if 'indent--FyTYr' in d.attrs.get('class', []) and not has_class(d.contents, 'indent--FyTYr'):
      yield [d.div.span.text, d.div.em.text]
   else:
      for i in filter(lambda x:x != '\n' and not isinstance(x, bs4.NavigableString), getattr(d, 'contents', [])):
         yield from get_sentences(i)


result = list(get_sentences(soup(requests.get('https://www.spanishdict.com/translate/rojo').text, 'html.parser').find('div', {'id':'dictionary-neodict-es'})))

要访问所需的字符串,请执行以下操作:

[['The sky turned red at sundown.', 'El cielo se tornó rojo al atardecer.'], ['No quiero ver esa propaganda roja.', "I don't want to see that red propaganda."], ['Ella cree que me veo mejor vestida de rojo, pero no estoy segura.', "She thinks I look best dressed in red, but I'm not sure."], ['Durante la Guerra Fría, a los izquierdistas se les llamaba rojos.', 'During the Cold War, the leftists were called reds.']]

输出:

print(result[0][0])

答案 2 :(得分:0)

您可以提供css选择器的列表,并生成匹配元素的列表,然后提供字典以查找翻译。切换顺序,使英语短语为键,而西班牙语为值。需要bs4 4.7.1+。匹配的项目都是您有词组的项目-翻译。

from bs4 import BeautifulSoup as bs
import requests

r = requests.get('https://www.spanishdict.com/translate/rojo')
soup = bs(r.content, 'lxml')
elems = [i.text for i in soup.select('span:has(+[class^="dash--"]), div:has(span:has(+[class^="dash--"])) em:not([title]), .ex, .ex_unit .tran_group, .idm, .idm_unit .tran_group, .cpd, .cpd_group .tran_group')]
results = {v if k!=elems[0] else k:k if k!=elems[0] else v for k,v in zip(elems[0::2],elems[1::2])} #reverse first item
print(results)

否则,您也可以列出切片对。