我正在尝试编写如下函数:
def get_urls(*urls,restrictions=None):
#here there should be some code that
#iterates through the urls and create
#a dictionary where the keys are the
#respective urls and their values are
#a list of the possible extentions. The
#function should return that dictionary.
首先,解释一下。如果我有一个网站:www.example.com,并且仅以下页面:www.example.com/faq,www.example.com/history和www.example.com/第2页。这将是应用程序:
In[1]: site = 'http://example.com'
In[2]: get_urls(site)
Out[2]: {'http://example.com':['/faq','/history','/page/2']}
我花了几个小时研究,到目前为止这似乎不可能!所以我错过了一些可以做到这一点的模块吗?是否存在但不存在于python中?如果是这样,用什么语言?
现在你可能想知道为什么有restrictions=None
,这就是原因:
我希望能够为可接受的网址添加限制。例如,restrictions='first'
可以使其只与一个'/'
一起存在的页面。这是一个例子:
In[3]: get_urls(site,restrictions='first')
Out[3]: {'http://example.com':['/faq','/history']}
我不需要继续解释限制的想法,但你了解它的必要性!有些网站,特别是社交网络,有一些疯狂的附加图片,除了这些外观很重要,同时保持原始页面包含所有照片。
所以是的,我绝对没有这个代码,但那是因为我不知道该怎么做!但我想我已经明确了我需要做什么,所以,这可能吗?如果有,怎么样?如果不是,为什么不呢?
修改
所以经过一些回答和评论后,这里有更多信息。我希望获得一个网址,不一定是域名,并返回一个字典,其中包含原始网址作为密钥,以及该网址的所有扩展名列表作为项目。以下是我之前的'example.com'
:
In[4]: site = 'http://example.com/page'
In[5]: get_urls(site)
Out[5]: {'http://example.com/page':['/2']}
爬行的例子和漂亮的汤很棒,但如果有一些网址没有直接链接在任何页面上,那么我找不到它。是的,这通常不是问题,但我希望能够!
答案 0 :(得分:8)
我将您的问题解释为“给定一个网址,在该网址下方找到存在的网址集”。 - 如果这不正确,请更新您的问题,这不是很清楚。
无法在域上发现整个有效路径集,您唯一的选择就是逐字遍历每个有效字符,例如: /
,/a
,/b
,/c
,...,/aa
,....并访问其中每个网址以确定服务器是否返回一个200或不。我希望很明显这根本不可行。
有可能(虽然有警告,网站所有者可能不喜欢它/阻止你)通过访问预定义的一组页面来抓取域,从页面中抓取所有链接,依次关注这些链接,并重复。这基本上就是谷歌所做的。这将为您提供一组域上的“可发现”路径,这些路径或多或少会完整,具体取决于您抓取的时间长度以及您在其网页中查找网址的频率。虽然更可行,但这仍然会很慢,并且不会为您提供“所有”网址。
你究竟要解决什么问题?爬行整个网站可能不是正确的方法,也许如果你解释一下你的最终目标,我们可以帮助你找出一个比你现在想象的更好的行动方案。
根本问题是对URL的“扩展”不一定有任何明确的含义。如果我运营一个网站(我的网站是http://example.com
,http://subdomain.example.com
还是http://example.com/page/
并不重要),我可以轻松配置我的服务器,以便成功响应您向其投放的任何请求。它可以简单地说“每个请求http://example.com/page/.*
返回Hello World.
”,突然间我有无数个有效页面。 Web服务器和URL类似,但从根本上说与硬盘驱动器和文件不同。与拥有有限数量文件的硬盘驱动器不同,网站可以说“是的,存在路径!”尽可能多的请求。这使得无法获得“所有可能的”URL。
除此之外,网络服务器通常不会希望您能够找到所有有效页面 - 也许只有您在登录时或在一天的特定时间才能访问它们,或者来自中国的请求 - 不要求URL始终存在,或者Web服务器告诉您它存在。我可以很容易地将我的无限URL行为置于http://example.com/secret/path/no/one/knows/about/.*
之下,除非我告诉你(或者你手动抓取所有可能的网址......),否则你永远不会知道它存在。
所以长话短说:不,不可能得到所有的URL,甚至是它们的一部分,因为从理论上讲它们可能是无数的,你无法知道这是不是情况下。
如果我可以添加限制,那将更容易!
我理解你为什么这么想,但不幸的是,事实并非如此。考虑像正则表达式这样的URL。有多少个字符串与正则表达式.*
匹配?无数,对吧? /path/.*
怎么样?减?还是/path/that/is/long/and/explicit/.*
?虽然可能看起来很直观,there are actually no fewer URLs that match the last case than the first。
既然如此,我对这一点的回答一直是关于一般情况,因为这就是你提出问题的方式。如果您明确定义和限制搜索空间,或放宽问题的要求,您可以得到答案。假设您改为说“是否可以获取此页面上列出的所有网址 并匹配我的过滤器?”绝对是答案是肯定的。在某些情况下(例如Apache's Directory Listing行为),这将巧合与原始问题的答案相同。然而,没有办法保证这实际上是正确的 - 我可以很容易地拥有一个目录列表,其中包含仍然与您的模式匹配的秘密,不公开的URL,并且您将找不到它们。
答案 1 :(得分:0)