如何刮取和提取到n级的链接,再次刮取数据并将其映射到python中的输出?

如何刮取和提取到n级的链接,再次刮取数据并将其映射到python中的输出?,python,web-scraping,web-crawler,Python,Web Scraping,Web Crawler,我正在用python学习网络爬行和抓取。我想在站点中有链接的地方收集数据,而在这些链接中有更多的链接。所以我想把数据刮到预定义的级别n。 这是我的基本代码 import requests from selenium import webdriver from requests_ntlm import HttpNtlmAuth from selenium import webdriver from selenium.webdriver.chrome.options import Options i

我正在用python学习网络爬行和抓取。我想在站点中有链接的地方收集数据,而在这些链接中有更多的链接。所以我想把数据刮到预定义的级别n。 这是我的基本代码

import requests
from selenium import webdriver
from requests_ntlm import HttpNtlmAuth
from selenium import webdriver
from selenium.webdriver.chrome.options import Options
import time
from bs4 import BeautifulSoup
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.common.by import By
from selenium.webdriver.support import expected_conditions as EC
from selenium.webdriver.support.ui import WebDriverWait
from selenium.common.exceptions import NoSuchElementException
from selenium.webdriver.support.ui import Select
from selenium.webdriver.common.action_chains import ActionChains
from webdrivermanager import GeckoDriverManager
import pickle
from selenium.webdriver.common.keys import Keys
from urllib.parse import urljoin
from seleniumrequests import Chrome
options = Options()

options.add_argument('--incognito')
options.add_argument('--headless')
options.add_argument("--no-sandbox")
options.add_argument('--disable-dev-shm-usage')
options.add_argument("--profile-directory=Default")
driver = webdriver.Chrome("./chromedriver",options=options)

web_url = 'https://spaceflightnow.com/'
driver.get("https://spaceflightnow.com/")
time.sleep(5)
soup = BeautifulSoup(driver.page_source,"lxml")
#section = soup.section
links=[]
for url in soup.find_all('a',href=True):
     links.append(urljoin(web_url,url.get('href')))
     #print(urljoin(web_url,url.get('href')))
links = list(filter(lambda x: x != web_url,links))
print(links)
这将打印第一页的多个链接。现在我想点击并转到后续级别中的所有链接,并再次将其刮除,以获得更多的内部链接。有可能从新闻提要内部再次显示相同的链接。所以我想知道的是,我应该采取什么样的方法来做这件事。我能理解我需要一棵树,但我不知道具体怎么做? 就像我在列表中创建一个列表一样,但是如何在n级之前动态地创建它呢?如何将其与保存在文件中的数据进行映射??有人能帮我吗?也许用样品溶液?
谢谢:)

我做了一个没有递归的例子——我想说它类似于算法

它将url保存在列表
[(url,级别),…]
中以控制级别,并将url保存在
set()
中以过滤访问的页面。它还过滤指向外部页面的链接

使用Firefox进行测试

import time
from bs4 import BeautifulSoup
from urllib.parse import urljoin
from selenium import webdriver
from selenium.webdriver.chrome.options import Options

# --- 

def get_links(driver, url):
    driver.get(url)
    time.sleep(5)

    soup = BeautifulSoup(driver.page_source,"lxml")

    links = []

    for new_url in soup.find_all('a', href=True):
         new_url = new_url.get('href')
         new_url = urljoin(url, new_url) 
         links.append(new_url)

    return links

# ---

options = Options()
options.add_argument('--incognito')
options.add_argument('--headless')
options.add_argument("--no-sandbox")
options.add_argument('--disable-dev-shm-usage')
options.add_argument("--profile-directory=Default")
driver = webdriver.Chrome("./chromedriver",options=options)
#driver = webdriver.Firefox()

# ---

domain = 'https://spaceflightnow.com/' # to filter external links
start_url = 'https://spaceflightnow.com/'
max_level = 2

links_visited = set([start_url])  # to test visited links
links_with_levels = [(start_url, 0)] # to control levels 

# ---

for link, level in links_with_levels:
    if level >= max_level:
        print('skip:', level, link)
        continue

    print('visit:', level, link)

    links = get_links(driver, link)

    print('found:', len(links))
    links = list(set(links) - links_visited)
    print('after filtering:', len(links))

    level += 1

    for new_link in links:
        if new_link.startswith(domain): # filter external links
            links_visited.add(new_link)
            links_with_levels.append( (new_link, level) )

# ---

for link, level in links_with_levels:
    print('skip:', level, link)

把代码放在函数中,用参数运行,这样你们就可以进行递归了。我知道,但假设当我得到链接1时,我会得到更多的链接,在它里面,所以我会再次得到所有的链接吗?喜欢里面的循环吗?或者我只是简单地将它附加到现有列表中,删除重复的链接并刮取数据?我应该检查链接是否重复出现吗?或者创建一个循环,从列表中获取第一个链接,访问它(使用返回新链接的函数),并在最后添加新链接-这样您可以访问列表中的所有链接。并始终检查列表中是否不存在新链接,这样您就不会多次访问同一链接。首先,创建获取一个链接的函数,只访问此页面并返回此页面上的所有链接,而不会访问找到的链接。然后你可以使用这个控制所有链接的in-loop,它只对新链接运行这个功能。顺便说一句:你可以给每个链接分配
level
,当你访问带有
level=n
的链接时,所有新链接都会有
level=n+1
这个代码会把链接刮到第二级吗?我需要进一步刮取?更改
max_level
以设置其他级别。但是
BFS
在进入下一个级别之前,首先获取第二个级别上的所有链接,因此在开始下一个级别之前需要时间。当然,我们会尝试让您知道,非常感谢您的帮助顺便说一句:)