打开网页并返回所有链接及其文本的dict



我正在尝试打开一个网页,并将所有链接作为一个字典返回,如下所示。

{"http://my.computer.com/some/file.html" : "link text"}

因此,链接将位于href=之后,文本将位于>和</a>之间

我使用https://www.yahoo.com/作为我的测试网站

我一直收到一个这样的错误:

'href=' in line:
TypeError: a bytes-like object is required, not 'str'

这是我的代码:

def urlDict(myUrl):
url = myUrl
page = urllib.request.urlopen(url)
pageText = page.readlines()
urlList = {}
for line in pageText:
if '<a href=' in line:
try:
url = line.split('<a href="')[-1].split('">')[0]
txt = line.split('<a href="')[-1].split('">')[-1].split('< /a>')[0]
urlList[url] = txt
except:
pass
return urlList

我做错了什么?我环顾四周,人们大多建议使用mygroup解析器。我会用它,但我不认为这会影响我的老师。

问题是您试图将字节字符串与常规字符串进行比较。如果将print(line)添加为for循环中的第一个命令,您会看到它将打印一个HTML字符串,但它的开头会有一个b',表明它不是utf-8编码。这让事情变得困难。在这里使用urllib的正确方法如下:

def url_dict(myUrl):
with urllib.request.urlopen(myUrl) as f:
s = f.read().decode('utf-8')

这将使s变量包含页面的整个文本。然后,您可以使用正则表达式来解析链接和链接目标。下面是一个示例,它将在没有HTML的情况下提取链接目标。

import urllib.request
import re
def url_dict():
#  url = myUrl
with urllib.request.urlopen('http://www.yahoo.com') as f:
s = f.read().decode('utf-8')

r = re.compile('(?<=href=").*?(?=")')
print(r.findall(s))
url_dict()

使用regex在字典中获取html和链接本身超出了您所在班级的范围,因此我绝对不建议将其提交给作业,尽管我建议学习它以备将来使用。

你会想按照建议使用BeautifulSoup,因为它让整个过程变得非常简单。文档中有一个示例,您可以剪切和粘贴来提取URL。

值得一提的是,这里有一种BeautifulSouprequests方法。

可以随意用urllib替换requests,但BeautifulSoup并不是一个很好的替代品。

import requests
from bs4 import BeautifulSoup
def get_links(url):
page = requests.get(url)
soup = BeautifulSoup(page.text, "html.parser")
return { a_tag['href']: a_tag.text for a_tag in soup.find_all('a') }
for link, text in get_links('https://www.yahoo.com/').items():
print(text.strip(), link)

最新更新