首页 > 解决方案 > 我想知道从 Beautiful soup 中新找到的链接是否已经在 queue.txt 文件和 crawled.txt 文件中

问题描述

我有一个漂亮的汤程序,我可以在其中找到网页上的所有链接并将其放入 queue.txt 文件中。然后程序从文件中获取每个链接并找到这些链接上的所有链接。然后将它们放入所有已爬取链接的 crawled.txt 文件中。

我想确保我没有重复,所以我希望程序通过 queue.txt 和 crawled.txt,如果刚刚找到的链接在这些文件中,那么不应该放入新找到的链接文件

我已经尝试这样做,以便它将新找到的链接打印到列表中并从那里删除重复项并将列表打印到 .txt 文件中,但它无法分辨队列文件中的内容,它只会从中删除重复项从一页新发现的链接。

这是代码:


from bs4 import BeautifulSoup
import requests
import re
from urllib.parse import urlparse


def get_links(base_url, file_name):
    page = requests.get(base_url)
    soup = BeautifulSoup(page.content, 'html.parser')
    single_slash = re.compile(r'^/\w')
    double_slash = re.compile(r'^//\w')

    parsed_uri = urlparse(base_url)
    domain_name = '{uri.scheme}://{uri.netloc}'.format(uri=parsed_uri)

    with open(file_name, "a") as f:
        for tag in soup.find_all('a'):
            link = str(tag.get('href'))

            if str(link).startswith("http"):
                link = link
                print(link)

            if double_slash.match(link):
                link = 'https:' + link
                print(link)

            if single_slash.match(link):
                link = domain_name + link
                print(link)

            if str(link).startswith("#"):
                continue

            if str(link).startswith("j"):
                continue

            if str(link).startswith('q'):
                continue

            if str(link).startswith('u'):
                continue

            if str(link).startswith('N'):
                continue

            if str(link).startswith('m'):
                continue

            try:
                f.write(link + '\n')
            except:
                pass

get_links('https://stackabuse.com/reading-and-writing-lists-to-a-file-in-python/', "queue.txt")

with open('queue.txt') as f:
    lines = f.read().splitlines()
print(lines)

for link in lines:

    if lines[0] == "/":
        del lines[0]

    print(lines[0])
    with open('crawled.txt', 'a') as h:
        h.write('%s\n' % lines[0])
        h.close()

    del lines[0]

    if lines[0] == "/":
        del lines[0]

    with open('queue.txt', 'w') as filehandle:
        for listitem in lines:
            filehandle.write('%s\n' % listitem)

        page_url = lines[0]
        get_links(page_url, "queue.txt")
    print(lines)

    with open('queue.txt') as f:
        lines = f.read().splitlines()

标签: pythontextbeautifulsouppython-requestsduplicates

解决方案


一般来说,对于 Python,当尝试删除重复项时,集合通常是一个不错的选择。例如:

lines = open('queue.txt', 'r').readlines()
queue_set = set(lines)
result = open('queue.txt', 'w')
for line in queue_set:
    result.write(line)

注意:这不会保留链接的顺序,但在这种情况下我没有看到原因。此外,这是改编自这个答案


推荐阅读