如何刮取和提取到n级的链接,再次刮取数据并将其映射到python中的输出?
我正在用python学习网络爬行和抓取。我想在站点中有链接的地方收集数据,而在这些链接中有更多的链接。所以我想把数据刮到预定义的级别n。 这是我的基本代码如何刮取和提取到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
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
在进入下一个级别之前,首先获取第二个级别上的所有链接,因此在开始下一个级别之前需要时间。当然,我们会尝试让您知道,非常感谢您的帮助顺便说一句:)