使用BeautifulSoup4与Google翻译。

4

我目前正在学习《自动化无聊工作》中的网页抓取部分,并尝试使用BeautifulSoup4编写提取谷歌翻译中翻译单词的脚本。

我检查了一个页面的HTML内容,其中“Explanation”是翻译后的单词:

<span id="result_box" class="short_text" lang="en">  
    <span class>Explanation</span>
</span>

使用BeautifulSoup4,我尝试了不同的选择器,但没有任何一个能返回翻译后的单词。这里是我尝试过的一些示例,但它们都没有返回任何结果:

soup.select('span[id="result_box"] > span')  
soup.select('span span') 

我甚至直接从开发者工具中复制了选择器,它给了我#result_box > span。但是这仍然没有返回任何结果。

有人能向我解释一下如何为我的目的使用BeautifulSoup4吗?这是我第一次使用BeautifulSoup4,但我认为我使用BeautifulSoup的方式或多或少是正确的,因为选择器

soup.select('span[id="result_box"]')

获取外部 span 元素

[<span class="short_text" id="result_box"></span>]

**不确定为什么缺少 'leng="en"' 部分,但我相当肯定已经找到了正确的元素。

以下是完整的代码:

import bs4, requests

url = 'https://translate.google.ca/#zh-CN/en/%E6%B2%BB%E5%85%B7'
res = requests.get(url)
res.raise_for_status
soup = bs4.BeautifulSoup(res.text, "html.parser")
translation = soup.select('#result_box span')
print(translation)

编辑:如果我将Google翻译页面保存为离线HTML文件,然后从该HTML文件创建一个soup对象,那么定位元素就不会有问题。

import bs4

file = open("Google Translate.html")
soup = bs4.BeautifulSoup(file, "html.parser")
translation = soup.select('#result_box span')
print(translation)

你的代码没问题,问题在于动态生成的内容,翻译在你获取的源中不可用。 - Padraic Cunningham
3个回答

3

result_box div是正确的元素,但是你的代码只在保存浏览器中看到的内容时有效,因为它包含动态生成的内容,使用requests只能获取源代码而不包括任何动态生成的内容。翻译是由ajax调用下面的url生成的:

"https://translate.google.ca/translate_a/single?client=t&sl=zh-CN&tl=en&hl=en&dt=at&dt=bd&dt=ex&dt=ld&dt=md&dt=qca&dt=rw&dt=rm&dt=ss&dt=t&ie=UTF-8&oe=UTF-8&source=bh&ssel=0&tsel=0&kc=1&tk=902911.786207&q=%E6%B2%BB%E5%85%B7"

对于你的请求,它返回:

[[["Fixture","治具",,,0],[,,,"Zhì jù"]],,"zh-CN",,,[["治 具",1,[["Fixture",999,true,false],["Fixtures",0,true,false],["Jig",0,true,false],["Jigs",0,true,false],["Governance",0,true,false]],[[0,2]],"治具",0,1]],1,,[["ja"],,[1],["ja"]]]

因此,您将不得不模仿请求,传递所有必要的参数,或者使用支持动态内容的工具,例如selenium


谢谢您的回答。我想我会使用Selenium重写代码。不过我有一个问题:您是怎么知道这个内容是动态生成的? - Ken Lin
@ken,最简单的方法是右键点击并选择查看源代码,您在那里看到的就是请求将要检索的内容。 - Padraic Cunningham
我明白了,将来使用requests时这将非常有用。一个小问题:动态生成的内容仍然算作HTML内容吗? - Ken Lin

0

只需尝试这个:

translation = soup.select('#result_box span')[0].text
print(translation)

1
嗨,使用它会给我一个错误“IndexError: list index out of range”,我相信这是因为翻译中没有结果,因此translation[0]无效。 - Ken Lin
删除“html.parser”然后再试。 - akash karothiya
1
嗨,那是用来从bs4中移除UserWarning的。不过,我已经将其删除,但是同样的错误仍然出现。我还编辑了我的示例代码,将其缩小为完整版本,以供其他用户尝试调试。如果您能够修复该代码并在自己的计算机上验证,那就太好了! - Ken Lin
检查一下soup对象的值,看看你的HTML字符串是否转换为树结构。 - akash karothiya
你能简单地向像我这样的初学者解释一下树形结构是什么样子吗?另外,我发现如果我将页面保存为html文件,在python中打开该html文件,并从中创建一个soup对象,你的代码也可以正常工作。我已经添加了我用于离线html文件的代码,请看一下。 - Ken Lin

0
你可以尝试这种不同的方法:
if filename.endswith(extension_file):
        with open(os.path.join(files_from_folder, filename), encoding='utf-8') as html:
            soup = BeautifulSoup('<pre>' + html.read() + '</pre>', 'html.parser')
            for title in soup.findAll('title'):
                recursively_translate(title)

完整代码请见此处:

https://neculaifantanaru.com/en/python-code-text-google-translate-website-translation-beautifulsoup-library.html

或者在这里:

https://neculaifantanaru.com/en/example-google-translate-api-key-python-code-beautifulsoup.html


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接