首页 > 编程问答 >在 Katana CLI 批处理中将发现的 URL 映射到原始 URL 时出现问题

在 Katana CLI 批处理中将发现的 URL 映射到原始 URL 时出现问题

时间:2024-07-24 05:54:32浏览次数:17  
标签:python web-crawler katana

我使用 Katana CLI 进行网络爬行,并使用 Python 包装器来管理批处理和输出解析。我的目标是将所有发现的 URL 映射回其原始 URL,但我面临着一些发现的 URL 无法正确映射的问题,特别是当域相似或涉及子域时。

以下是我的设置:| ||输入:powerui.f​​oo.com、acnmll-en.foo.com

class KatanaData:
    def __init__(self, domain: str, original_url: str, id: str):
        self._original_url = original_url
        self._domain = domain
        self._id = id
        self._discovered_urls = []
        self._error = None
        self._processing_time = None

def run_katana(batch: Dict, timeout=120):
    url_list = create_url_list(batch)

    tmp = 'tmp'
    output_dir = f'{tmp}/SRD_output'
    
    cmd = [
        'katana', '-u', url_list, '-headless', '-headless-options', '--disable-gpu', '-field-scope', 'dn', '-depth', '5',
         '-extension-filter', 'css', '-timeout', '10', '-crawl-duration', f'{timeout}s', '-srd', output_dir
    ]
    error_message = None
    start_time = time.time()
    process = None
    try:
        process = subprocess.run(cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, text=True, timeout=timeout)
        processing_time = round(time.time() - start_time, 2)

        if process.returncode == 0:

        else:
            log_with_location(f'Batch for {url_list} failed in {processing_time}')
            error_message = process.stderr.strip()
    except subprocess.TimeoutExpired:
        if process:
            process.kill()
        log_with_location(f'Batch for {url_list} timed out after {timeout} seconds')
        error_message = "Process timed out"
    finally:
        try:

            parse_srd(output_dir, batch)
        except (FileNotFoundError, ValueError) as e:
            error_message = str(e)
        kill_katana_processes()
        cleanup_temp(tmp)
    return error_message

def parse_srd(output_dir, batch: Dict):
    log_with_location(f'Starting parse_srd for {len(batch)} urls')
    output_file = f'{output_dir}/index.txt'
    if not os.path.exists(output_file):
        log_with_location(f'{output_file} not found in {output_dir}', logging.ERROR)
        raise FileNotFoundError(f'{output_file} not found')

    with open(output_file, 'r') as file:
        lines = file.readlines()
        for line in lines:
            parts = line.split()
            if len(parts) >= 3:
                file_path = parts[0]
                discovered_url = parts[1]
                status = parts[2]
                original_url = find_original_url(discovered_url, batch)
                if original_url:
                    batch[original_url]._discovered_urls.append((discovered_url, status))
                else:
                    print(f"Warning: Original URL not found for discovered URL {discovered_url}")

def find_original_url(discovered_url, batch: Dict):
    discovered_netloc = urlparse(discovered_url).netloc
    for domain, katanaData in batch.items():
        original_netloc = urlparse(katanaData._original_url).netloc
        if discovered_netloc == original_netloc or discovered_netloc.endswith(f".{original_netloc}"):
            return domain
    return None

def create_url_list(batch: Dict):
    return ','.join([data._original_url for data in batch.values()])

Katana 的 -srd 标志会将 http 请求/响应存储到自定义目录。它还创建一个 index.txt 文件,其中包含三列:http 请求/响应的位置、发现的 url 和状态。

ex: tmp/SRD_output/powerui.f​​oo.com/87ef37260d0375e204e8e16d00768920fb2bc5eb.txt

https://powerui.f​​oo.com/powerui/vendor/bower-asset/masonry/dist/masonry.pkgd.min.js?v20240706122948 (好的) tmp/SRD_output/newsroom.foo.com/85e443613511a3a41f1d20568d5ecc8506b57e43.txt https://newsroom.foo.com/scripts/scripts.js (确定) tmp/SRD_output/investor.foo.com/78e3fd823de018fa2323b59ae7ce34b54d8e90d0.txt https://investor.foo.com/javascripts/home-banner.js?revision=d6483dcf-da80-4ab1-a5b7-a507a5dcd426 (确定) 如何确保每个发现的 URL 都正确映射回其原始 URL,尤其是在处理类似的域时? 在这种情况下,是否有更好的策略来处理域匹配? 有没有办法增强 find_original_url 函数以更准确地处理这些情况?

简单域匹配 - 使用精确域匹配或检查发现的域是否以原始域结尾。 子域处理 - 考虑子域,但当域相似时仍然面临问题。 JSONL 标志 - 以 jsonl 格式输出,有时我可以在其中看到源 URL。对于每个 jsonl 行,响应可以是有效的,也可以是错误的。 一次处理一个 - 这非常慢,我想利用该工具具有的并发性和并行性。

警告:未找到已发现 URL 的原始 URL

https://newsroom.foo.com/scripts /scripts.js 警告:未找到已发现 URL 的原始 URL https://investor.foo.com/javascripts/home-banner.js?revision=d6483dcf-da80-4ab1-a5b7-a507a5dcd426|| |问题是某些发现的 URL 无法正确映射回原始 URL,尤其是当域相似时。例如,如果我有两个原始 URL,其域分别为 acnml-en.foo 和 powerui.f​​oo,则发现的来自子域或类似域的 URL 有时无法正确映射。 https://investor.foo.com/javascripts/home-banner.js?revision=d6483dcf-da80-4ab1-a5b7-a507a5dcd426

The issue is that some discovered URLs do not map back to the original URLs correctly, especially when domains are similar. For example, if I have two original URLs with domains of acnml-en.foo and powerui.foo, discovered URLs from subdomains or similar domains are sometimes not mapped correctly.


遇到的問題很常見,因為依賴簡單的字串匹配來找出原始 URL 可能不可靠,尤其是在處理複雜的網站結構和子網域時。的 find_original_url 函式目前會檢查完全相符或子網域包含,這可能會導致當多個原始 URL 共用通用子網域時出現錯誤分類。

以下是如何增強的方法以提高準確性:

  1. 使用 Katana 的 -jsonl 標誌: 正如所提到的,Katana 可以輸出為 JSONL 格式,其中包含更多資訊,包括參考者標頭,這在確定原始 URL 時非常有用。修改的 run_katana 函式以包含 -jsonl 標誌,並建立一個新目錄來儲存輸出: python cmd = [ 'katana', '-u', url_list, '-headless', '-headless-options', '--disable-gpu', '-field-scope', 'dn', '-depth', '5', '-extension-filter', 'css', '-timeout', '10', '-crawl-duration', f'{timeout}s', '-srd', output_dir, '-jsonl', output_dir ]

  2. 從 JSONL 輸出中解析參考者: 更新的 parse_srd 函式以解析 JSONL 檔案,並使用 referrer 資訊來準確地找出原始 URL。

```python import json

def parse_srd(output_dir, batch: Dict): log_with_location(f'開始針對 {len(batch)} 個 URL 剖析 srd') for filename in os.listdir(output_dir): if filename.endswith(".jsonl"): with open(os.path.join(output_dir, filename), 'r') as f: for line in f: data = json.loads(line) discovered_url = data.get('url') status = data.get('status') referrer = data.get('referrer')

                 if discovered_url and referrer: 
                     original_url = find_original_url(discovered_url, referrer, batch)
                     if original_url:
                         batch[original_url]._discovered_urls.append((discovered_url, status))
                     else:
                         print(f"警告:找不到已發現 URL 的原始 URL {discovered_url}")

def find_original_url(discovered_url, referrer, batch: Dict): for original_url, katanaData in batch.items(): if referrer.startswith(original_url): return original_url return None ```

  1. 處理邊緣案例: 雖然參考者方法應該可以更準確地解決大多數情況,但可能仍然會遇到某些邊緣案例。考慮為無法使用參考者解析的 URL 實作額外的邏輯。例如,可以:

    • 放寬網域名稱匹配: 允許與原始 URL 的網域名稱進行部分匹配,例如使用 urllib.parse.urlparse 提取主機名並檢查相似性。
    • 使用 URL 路徑相似性: 如果網域名稱匹配不明確,請比較已發現 URL 與每個原始 URL 的路徑結構,以找出最相似的匹配。
    • 維護已發現 URL 的記錄: 在 Katana 執行期間,追蹤每個原始 URL 發現的 URL。如果在使用其他方法後 URL 仍然不明確,可以使用此記錄嘗試推斷原始 URL。

通過使用這些增強功能,的腳本將能夠更準確可靠地將已發現的 URL 映射回其原始 URL,即使在處理複雜的網站和子網域時也是如此。

請記住,即使有這些改進,完美地將每個 URL 映射回其確切來源仍然是一項挑戰,尤其是在處理複雜的網站架構和客戶端端重定向時。持續測試和改進的邏輯對於盡可能提高準確性至關重要。

标签:python,web-crawler,katana
From: 78785687

相关文章

  • 使用 Python-PlexAPI 获取 plex 上所有好友的关注列表
    有关如何接收我的plex服务器上所有用户的监视列表的任何提示。我正在根据一些规则创建自动删除,其中一个规则是,如果电影位于用户观看列表中,则不应删除该电影。我遇到了麻烦,因为所有与观看列表相关的内容都在MyPlexAccount上。lexapi.myplex.MyPlexAccount具有我的用......
  • 如何在 Python 中查看与 Azure OpenAI 助手关联的所有上传文件?
    我正在使用Python对文档中的问题进行基准测试,并在jupyter笔记本中实例化了我的助手。我想确认助手是否有我上传的文件,但似乎找不到有关此功能将使用什么功能的文档。使用适用于AzureOpenAI的最新版本的PythonAPI。目前,无法使用AzureOpenAI的PythonAPI直接查看......
  • 如何在Python中计算小数?
    我正在创建一个计算器来用python计算企业的利润,但到目前为止我只能使用整数。这是我的代码示例:Gross=int(input("PleaseentertotalGrossRevenuefortheFiscalYear"))NetTaxes=int(Gross)*0.1所以我将会计年度的总收入乘以按“税率”计算,但我只能使用......
  • 如何使用 Python 打开 Google Firestore 上的特定数据库?
    我正在使用Firebase并使用以下代码从Firestore设置/检索文档:importfirebase_adminfromfirebase_adminimportcredentials,firestorecred=credentials.ApplicationDefault()firebase_admin.initialize_app(cred,options={"projectId":"huq-jimbo"})fires......
  • 如何使用 Python 和 Numpy 重现 Matlab 文件读取以解码 .dat 文件?
    我有一个Matlab脚本,可以读取编码的.dat文件,对其进行解码并保存。我试图使用numpy将其转换为Python。我发现对于同一个文件,我得到不同的输出结果(python数字没有意义)。该代码最初作为从串行端口读取的脚本的一部分运行,因此是数据的结构。我首先认为位移是问题所在,因为......
  • 在Python中调整pdf页面大小
    我正在使用python裁剪pdf页面。一切正常,但如何更改页面大小(宽度)?这是我的裁剪代码:input=PdfFileReader(file('my.pdf','rb'))p=input.getPage(1)(w,h)=p.mediaBox.upperRightp.mediaBox.upperRight=(w/4,h)output.addPage(p)当我裁剪页面时,我也需要......
  • 如何使用 python 更改资源管理器窗口中的路径?
    没有人知道如何在不使用python打开新实例的情况下更改资源管理器窗口中的当前路径吗?例如,如果用户使用C:\Users\User打开资源管理器窗口。然后我必须将该路径更改为C:\Windows\System32例如。提前致谢。很遗憾,无法直接使用Python更改现有文件资源管理器窗口的......
  • python 以及将数组传递给函数的问题
    我需要求解一些常微分方程$\frac{dy}{dx}=f(x)=x^2ln(x)$并继续在限制0之间创建数组xpt。<=xpt<=2因为我必须小心xpt=0,所以我将函数定义如下deff(x):ifx<=1.e-6:return0.else:returnnp.square(x)*np.log(x)我的调用程序读取Np......
  • 如果 Python 脚本正在使用文件夹,如何在文件资源管理器中进行更改时防止 Windows 的“
    我有一个简单的脚本,显示在QTreeView中的QListView中选择的目录的内容,我想添加打开文件资源管理器的功能,以让用户编辑目录内的内容。但是,添加新的文件夹和文件可以,但删除或移动文件夹或文件会提示“文件夹正在使用”错误:此操作无法完成,因为该文件已在另一个程......
  • 如何使用 Python API 获取每个模型的活跃用户列表、最后登录信息
    我想通过PythonAPI获取我的dbt项目的所有模型中的活动或非活动用户列表。这可能吗?我尝试列出模型,但无法获取用户信息,如用户名、项目、以及上次活动或上次登录。不幸的是,dbt本身并不跟踪你所寻找的用户活动数据(最后登录、活跃用户等)。dbt的主要功能是转换数据,而不......