如何使用Python获取域中的所有链接?
我想使用Python获取给定“根”URL(在列表中)的域中的所有链接。假设给定一个URL,它应该返回与根URL相同域的页面上的所有链接,然后在每个链接上递归访问它们并提取相同域的所有链接,依此类推。我所说的同一个域名的意思是,如果给定的唯一链接,我想回来是。。。任何外部的东西,例如,应该被丢弃。如何使用Python实现这一点 编辑:我尝试使用lxml。我认为这并不完全有效,我也不确定如何考虑到已经处理过的页面的链接(导致无限循环)如何使用Python获取域中的所有链接?,python,web-scraping,beautifulsoup,lxml,Python,Web Scraping,Beautifulsoup,Lxml,我想使用Python获取给定“根”URL(在列表中)的域中的所有链接。假设给定一个URL,它应该返回与根URL相同域的页面上的所有链接,然后在每个链接上递归访问它们并提取相同域的所有链接,依此类推。我所说的同一个域名的意思是,如果给定的唯一链接,我想回来是。。。任何外部的东西,例如,应该被丢弃。如何使用Python实现这一点 编辑:我尝试使用lxml。我认为这并不完全有效,我也不确定如何考虑到已经处理过的页面的链接(导致无限循环) ~根据你问题的标签,我猜你用的是漂亮的汤。 首先,您显然需要下载
~根据你问题的标签,我猜你用的是漂亮的汤。 首先,您显然需要下载该网页,例如使用urllib.request。当你把里面的东西串起来后,你就把它传给美丽的汤。在此之后,您可以找到与soup.find_all('a')的所有链接,假设soup是您美丽的soup对象。之后,您只需检查HREF:
最简单的版本是只检查href中是否有“”,但这不会捕获相对链接。我猜一些野生正则表达式可以(用“www.example.com”或“/”或“?”(php)开始查找所有内容),或者您可以查找包含www但不包含www.example.com的所有内容并将其丢弃,等等。正确的策略可能取决于您正在删除的网站,它是一种编码风格。您可以使用正则表达式过滤掉此类链接 乙二醇
上面的代码片段包含从德国汉莎航空公司arlines网站删除URL所需的模块。这里唯一的附加功能是您可以指定要递归刮取的深度 以下是我所做的工作,只提供了完整的URL。快,但有点脏
import requests
import re
domain = u"stackoverflow.com"
http_re = re.compile(u"(http:\/\/" + domain + "[\/\w \.-]*\/?)")
visited = set([])
def visit (url):
visited.add (url)
extracted_body = requests.get (url).text
matches = re.findall (http_re, extracted_body)
for match in matches:
if match not in visited :
visit (match)
visit(u"http://" + domain)
print (visited)
@namita的代码中有一些bug。我修改了它,现在它工作得很好
import sys
import requests
import hashlib
from bs4 import BeautifulSoup
from datetime import datetime
def get_soup(link):
"""
Return the BeautifulSoup object for input link
"""
request_object = requests.get(link, auth=('user', 'pass'))
soup = BeautifulSoup(request_object.content, "lxml")
return soup
def get_status_code(link):
"""
Return the error code for any url
param: link
"""
try:
error_code = requests.get(link).status_code
except requests.exceptions.ConnectionError:
error_code = -1
return error_code
def find_internal_urls(main_url, depth=0, max_depth=2):
all_urls_info = []
soup = get_soup(main_url)
a_tags = soup.findAll("a", href=True)
if main_url.endswith("/"):
domain = main_url
else:
domain = "/".join(main_url.split("/")[:-1])
print(domain)
if depth > max_depth:
return {}
else:
for a_tag in a_tags:
if "http://" not in a_tag["href"] and "https://" not in a_tag["href"] and "/" in a_tag["href"]:
url = domain + a_tag['href']
elif "http://" in a_tag["href"] or "https://" in a_tag["href"]:
url = a_tag["href"]
else:
continue
# print(url)
status_dict = {}
status_dict["url"] = url
status_dict["status_code"] = get_status_code(url)
status_dict["timestamp"] = datetime.now()
status_dict["depth"] = depth + 1
all_urls_info.append(status_dict)
return all_urls_info
if __name__ == "__main__":
url = # your domain here
depth = 1
all_page_urls = find_internal_urls(url, 0, 2)
# print("\n\n",all_page_urls)
if depth > 1:
for status_dict in all_page_urls:
find_internal_urls(status_dict['url'])
从问号上看,你似乎已经知道该用什么了。也许你可以展示一下你的尝试,否则我认为这个问题太笼统了。有一些网络抓取框架,比如说,可能会对你有所帮助。这个问题很难解决,因为页面中的一些链接没有协议前缀,并且提供了本地路径。“.”是有效的URL。你想跟随什么而不是跟随什么?我只想跟随以根URL为前缀的任何内容。但是,某些相对链接的前缀不是根URL,但如果我在它们前面加上根URL,它们将是有效的。我也想要这些。这是有道理的,但这是如何重现的呢?它似乎只找到第一个“级别”的链接。你添加深度,它就会搜索到那么多的深度。但是find_internal_URL实际上是在哪里被自己调用的,从而在链接上递归?我提供了模块,你可以根据需要在任何地方使用该功能!我认为这行不通。您正在对“查找内部URL”中的所有页面URL进行变异。因此,在main方法中,您正在更改循环中迭代的内容,python将其视为一次聚会犯规。
import sys
import requests
import hashlib
from bs4 import BeautifulSoup
from datetime import datetime
def get_soup(link):
"""
Return the BeautifulSoup object for input link
"""
request_object = requests.get(link, auth=('user', 'pass'))
soup = BeautifulSoup(request_object.content)
return soup
def get_status_code(link):
"""
Return the error code for any url
param: link
"""
try:
error_code = requests.get(link).status_code
except requests.exceptions.ConnectionError:
error_code =
return error_code
def find_internal_urls(lufthansa_url, depth=0, max_depth=2):
all_urls_info = []
status_dict = {}
soup = get_soup(lufthansa_url)
a_tags = soup.findAll("a", href=True)
if depth > max_depth:
return {}
else:
for a_tag in a_tags:
if "http" not in a_tag["href"] and "/" in a_tag["href"]:
url = "http://www.lufthansa.com" + a_tag['href']
elif "http" in a_tag["href"]:
url = a_tag["href"]
else:
continue
status_dict["url"] = url
status_dict["status_code"] = get_status_code(url)
status_dict["timestamp"] = datetime.now()
status_dict["depth"] = depth + 1
all_urls_info.append(status_dict)
return all_urls_info
if __name__ == "__main__":
depth = 2 # suppose
all_page_urls = find_internal_urls("someurl", 2, 2)
if depth > 1:
for status_dict in all_page_urls:
find_internal_urls(status_dict['url'])
import requests
import re
domain = u"stackoverflow.com"
http_re = re.compile(u"(http:\/\/" + domain + "[\/\w \.-]*\/?)")
visited = set([])
def visit (url):
visited.add (url)
extracted_body = requests.get (url).text
matches = re.findall (http_re, extracted_body)
for match in matches:
if match not in visited :
visit (match)
visit(u"http://" + domain)
print (visited)
import sys
import requests
import hashlib
from bs4 import BeautifulSoup
from datetime import datetime
def get_soup(link):
"""
Return the BeautifulSoup object for input link
"""
request_object = requests.get(link, auth=('user', 'pass'))
soup = BeautifulSoup(request_object.content, "lxml")
return soup
def get_status_code(link):
"""
Return the error code for any url
param: link
"""
try:
error_code = requests.get(link).status_code
except requests.exceptions.ConnectionError:
error_code = -1
return error_code
def find_internal_urls(main_url, depth=0, max_depth=2):
all_urls_info = []
soup = get_soup(main_url)
a_tags = soup.findAll("a", href=True)
if main_url.endswith("/"):
domain = main_url
else:
domain = "/".join(main_url.split("/")[:-1])
print(domain)
if depth > max_depth:
return {}
else:
for a_tag in a_tags:
if "http://" not in a_tag["href"] and "https://" not in a_tag["href"] and "/" in a_tag["href"]:
url = domain + a_tag['href']
elif "http://" in a_tag["href"] or "https://" in a_tag["href"]:
url = a_tag["href"]
else:
continue
# print(url)
status_dict = {}
status_dict["url"] = url
status_dict["status_code"] = get_status_code(url)
status_dict["timestamp"] = datetime.now()
status_dict["depth"] = depth + 1
all_urls_info.append(status_dict)
return all_urls_info
if __name__ == "__main__":
url = # your domain here
depth = 1
all_page_urls = find_internal_urls(url, 0, 2)
# print("\n\n",all_page_urls)
if depth > 1:
for status_dict in all_page_urls:
find_internal_urls(status_dict['url'])