【问题标题】:Parse HTML to edit links解析 HTML 以编辑链接
【发布时间】:2013-07-22 04:10:05
【问题描述】:

我正在尝试解析 HTML 文件(demo.html 以使所有相对链接成为绝对链接。这是我尝试在 Python 脚本中执行此操作的方法 -

from bs4 import BeautifulSoup
f = open('demo.html', 'r')
html_text = f.read()
f.close()
soup = BeautifulSoup(html_text)
for a in soup.findAll('a'):
    for x in a.attrs:
        if x == 'href':
            temp = a[x]
            a[x] = "http://www.esplanade.com.sg" + temp
for a in soup.findAll('link'):
    for x in a.attrs:
        if x == 'href':
            temp = a[x]
            a[x] = "http://www.esplanade.com.sg" + temp
for a in soup.findAll('script'):
    for x in a.attrs:
        if x == 'src':
            temp = a[x]
            a[x] = "http://www.esplanade.com.sg" + temp
f = open("demo_result.html", "w")
f.write(soup.prettify().encode("utf-8"))

但是,输出文件demo_result.html 包含许多意外更改。例如,

<script type="text/javascript" src="/scripts/ddtabmenu.js" />  
/***********************************************
* DD Tab Menu script- (c) Dynamic Drive DHTML code library (www.dynamicdrive.com)
* + Drop Down/ Overlapping Content- 
* This notice MUST stay intact for legal use
* Visit Dynamic Drive at http://www.dynamicdrive.com/ for full source code
***********************************************/   
</script>

更改为

 <script src="http://www.esplanade.com.sg/scripts/ddtabmenu.js" type="text/javascript">
 </script>
</head>
<body>
 <p>
  /***********************************************
   * DD Tab Menu script- (c) Dynamic Drive DHTML code library (www.dynamicdrive.com)
   * + Drop Down/ Overlapping Content- 
   * This notice MUST stay intact for legal use
   * Visit Dynamic Drive at http://www.dynamicdrive.com/ for full source code
   ***********************************************/

谁能告诉我哪里出错了?

感谢和最热烈的问候。

【问题讨论】:

  • 我的工作正常。
  • @user1471175 - 你是什么意思?它是否只转换链接而不像我在问题中提到的那样更改 HTML 的其他部分?
  • 对不起,我正在寻找错误的错误 :)

标签: python html hyperlink beautifulsoup web-crawler


【解决方案1】:

它接缝漂亮的汤 4 有问题 只需将 Beautifult 汤降级到版本 3 你的问题会解决的

import  BeautifulSoup      #This is version 3 not version 4
f = open('demo.html', 'r')
html_text = f.read()
f.close()
soup = BeautifulSoup.BeautifulSoup(html_text)
print soup.contents
for a in soup.findAll('a'):
    for x in a.attrs:
        if x == 'href':
            temp = a[x]
            a[x] = "http://www.esplanade.com.sg" + temp
for a in soup.findAll('link'):
    for x in a.attrs:
        if x == 'href':
            temp = a[x]
            a[x] = "http://www.esplanade.com.sg" + temp
for a in soup.findAll('script'):
    for x in a.attrs:
        if x == 'src':
            temp = a[x]
            a[x] = "http://www.esplanade.com.sg" + temp
f = open("demo_result.html", "w")
f.write(soup.prettify().encode("utf-8"))

【讨论】:

  • 谢谢@user1471175 :D 成功了。我已经对代码进行了一些编辑,以消除编码/解码错误:)
【解决方案2】:

您的 HTML 代码有点乱。你已经关闭了script 标签,你又要关闭它了

<script type="text/javascript" src="/scripts/ddtabmenu.js" /></script>

它破坏了 DOM。只需从&lt;script type="text/javascript" src="/scripts/ddtabmenu.js" /&gt; 末尾删除/

【讨论】:

  • 诚实的问题,BeatifulSoap 不应该处理损坏的 HTML 吗?
  • 确实这是美汤版本 4 的问题,版本 3 工作正常
  • @twil 我同意这很混乱。但是,我无法控制 HTML,因为我正在尝试抓取网页。当然,我可以解析 HTML 以使其更好,但同样,如果我不必这样做,我会更喜欢 :)
  • 我认为没有必要在前或后解析。如果beautifulsoup3 满足您的需求,那就坚持下去。如果你想使用 bs4,你可以尝试不同的parsers
【解决方案3】:

如前所述,回归到 BeautifulSoup 3 可以解决问题。另外,添加这样的 url 会对 html 锚点和 javascript 引用产生问题,所以我更改了代码:

import re
import BeautifulSoup

with open("demo.html", "r") as file_h:
    soup = BeautifulSoup.BeautifulSoup(file_h.read())

url = "http://www.esplanade.com.sg/"
health_check = lambda x: bool(re.search("^(?!javascript:|http://)[/\w]", x))
replacer = lambda x: re.sub("^(%s)?/?" % url, url, x)

for soup_tag in soup.findAll(lambda x: x.name  in ["a", "img", "link", "script"]):

    if(soup_tag.has_key("href") and  health_check(soup_tag["href"])):
        soup_tag["href"] = replacer(soup_tag["href"])

    if(soup_tag.has_key("src") and health_check(soup_tag["src"])):
        soup_tag["src"] = replacer(soup_tag["src"])

with open("demo_result.html", "w") as file_h:
    file_h.write(soup.prettify().encode("utf-8"))

【讨论】:

  • 您好,感谢您尝试改进我的代码。但是我对正则表达式不是很熟悉。因此,如果您还可以详细解释这些正则表达式期望捕获的模式,我将不胜感激。非常感谢:)
  • 当然,health_check 是一个函数,它接受一个 href 字符串并检查是否:a) 它不是以“javascript:”或“http://”开头; b) 它以正斜杠或字母数字字符开头。 replacer 是一个对 href 或 src 字符串执行正则表达式替换的函数;它从字符串的开头替换到并包括:a) url(如果存在)和 b) 正斜杠(如果存在),带有 url 本身。
猜你喜欢
  • 2016-05-08
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-01-28
  • 2010-09-12
  • 1970-01-01
  • 2015-02-08
  • 2015-11-12
相关资源
最近更新 更多