【问题标题】:Joining URL throwing exception加入 URL 抛出异常
【发布时间】:2015-05-09 15:38:51
【问题描述】:

我有两个变量,一个包含绝对 URL,另一个包含另一个部分的相对路径。首先,我尝试了一个简单的串联。

absolute_url = www.example.com
relative_url = /downloads/images
url = absolute_url + relative_url

当我打印 url 变量时,我有一个格式正确的 URL。但是当我尝试使用 requests 或 urllib2 来检索数据时,大约有一半的时间会抛出异常:'NoneType' object has no attribute 'getitem'

然后我研究并认为也许我应该使用 urllib.urlparse.urljoin() 来执行此操作,但我仍然收到错误。

但令我感兴趣的是,它有时有效,有时无效。关于这里发生了什么的任何想法?

编辑

下面是实际代码:

url = "http://www.hdwallpapers.in"
html = requests.get(url)
soup = BeautifulSoup(html.text)

categories = ("Nature", "Animals & Birds", "Beach", "Bikes", "Cars","Dreamy & Fantasy", "Others", "Travel & World")
random_category = random.randint(0, len(categories)) - 1
selected_category = categories[random_category]
selected_category_url = soup.find('a', text=selected_category)

category_page_url_join = urlparse.urljoin(url, selected_category_url['href'])
category_page_html = requests.get(category_page_url_join)

【问题讨论】:

  • 显示一个出错的实际示例,包括您对 requests/urllib2 的使用。

标签: python web-scraping urllib


【解决方案1】:

你有一个categories的列表:

categories = ("Nature", "Animals & Birds", "Beach", "Bikes", "Cars","Dreamy & Fantasy", "Others", "Travel & World")

然后你随机选择一个并搜索它:

random_category = random.randint(0, len(categories)) - 1
selected_category = categories[random_category]
selected_category_url = soup.find('a', text=selected_category)

这将更容易编写和阅读:

selected_category_url = soup.find('a', text=random.choice(categories))

现在你的问题无疑来自:

category_page_url_join = urlparse.urljoin(url, selected_category_url['href'])

这意味着您的selected_category_url 最终成为None,因为您的soup.find 实际上没有找到任何东西。所以实际上你正在尝试运行None['href'](当然失败了......)

请注意,requests 不会进行任何 HTML 实体转义,但BeautifulSoup 会尽可能地尝试,因此,例如:

from bs4 import BeautifulSoup
soup1 = BeautifulSoup('smith & jones')
soup2 = BeautifulSoup('smith & jones')
soup1, soup2
(<html><body><p>smith &amp; jones</p></body></html>,
 <html><body><p>smith &amp; jones</p></body></html>)

所以,既然您说“大约有一半的时间”,那是因为您有 3 个要搜索的选项不匹配....尝试将 categories 中的 &amp;amp; 替换为&amp;amp; 代替。

【讨论】:

  • 感谢对我的脚本提出的改进建议。但不幸的是,代码仍然崩溃。我测试了打印 urlparse.urljoin() 的返回,我总是有一个格式良好的 url。我可以在网络浏览器上正常打开它。但是当我作为参数发送到 requests.get() 时,它就会崩溃。欢迎任何更多改进的想法。
  • @XVirtusX 您尝试打印了多少次?这是您的异常可能来自的唯一地方...如果不是 - 您需要将完整的回溯添加到您的问题...requests.get 不会给出您指定的异常
  • 好吧,在调试了一段时间并阅读了更多 urlparse 的文档之后,我尝试在 urljoin 的返回上使用 urlparse.urlsplit(),然后使用 geturl(),它终于奏效了。不知道它为什么起作用。看来我遇到了 python 晦涩的内部结构..
猜你喜欢
  • 2015-07-16
  • 1970-01-01
  • 1970-01-01
  • 2013-05-24
  • 1970-01-01
  • 2015-01-28
  • 2011-05-30
  • 1970-01-01
  • 2011-02-25
相关资源
最近更新 更多