С помощью Beautiful Soup рекурсивно очистите все подссылки сайта на Python. - PullRequest
0 голосов
/ 10 мая 2018

НОВОЕ ОБНОВЛЕНИЕ: Я сокращаю свой вопрос до того, как рекурсивно получать все ссылки с сайта, включая подсылки каждой страницы и т. Д.

Мне кажется, я знаю, как получить все подссылки одной страницы:

from bs4 import BeautifulSoup
import requests
import re

def get_links(site, filename):
    f=open(filename, 'w')
    url = requests.get(site)
    data = url.text
    soup = BeautifulSoup(data, 'lxml')
    for links in soup.find_all('a'):
        f.write(str(links.get('href'))+"\n")
    f.close()

r="https://en.wikipedia.org/wiki/Main_Page"
filename="wiki"
get_links(r,filename)

Как мне рекурсивно убедиться, что все ссылки на сайте также собраны и записаны в один файл?

Итак, я попробовал это, и он даже не компилируется.

def is_url(link):
    #checks using regex if 'link' is a valid url
    url = re.findall('http[s]?://(?:[a-zA-Z]|[0-9]|[$-_@.&+#]|[!*/\\,() ]|(?:%[0-9a-fA-F][0-9a-fA-F]))+', link)
    return (" ".join(url)==link)

def get_links(site, filename):
    f=open(filename, 'a')
    url = requests.get(site)
    data = url.text
    soup = BeautifulSoup(data, 'lxml')
    for links in soup.find_all('a'):
        if is_url(links):
            f.write(str(links.get('href'))+"\n")
            get_links(links, filename)
    f.close()

1 Ответ

0 голосов
/ 12 мая 2018

Отвечая на ваш вопрос, я получу все ссылки на страницу с помощью beautilfulsoup и сохраню их в файл:

from bs4 import BeautifulSoup
import requests


def get_links(url):
    response = requests.get(url)
    data = response.text
    soup = BeautifulSoup(data, 'lxml')

    links = []
    for link in soup.find_all('a'):
        link_url = link.get('href')

        if link_url is not None and link_url.startswith('http'):
            links.append(link_url + '\n')

    write_to_file(links)
    return links


def write_to_file(links):
    with open('data.txt', 'a') as f:
        f.writelines(links)


def get_all_links(url):
    for link in get_links(url):
        get_all_links(link)


r = 'https://en.wikipedia.org/wiki/Main_Page'
write_to_file([r])
get_all_links(r)

Это, однако, не предотвратит циклы (что приведет к бесконечной рекурсии). Для этого вы можете использовать set для хранения уже посещенных ссылок и не посещать их снова.

Вам действительно стоит подумать об использовании чего-то вроде Scrapy для такого рода задач. Я думаю, что CrawlSpider - это то, на что вы должны обратить внимание.

Для извлечения URL-адресов из домена wikipedia.org вы можете сделать что-то вроде этого:

from scrapy.spiders import CrawlSpider
from scrapy.spiders import Rule
from scrapy.linkextractors import LinkExtractor

from scrapy import Item
from scrapy import Field


class UrlItem(Item):
    url = Field()


class WikiSpider(CrawlSpider):
    name = 'wiki'
    allowed_domains = ['wikipedia.org']
    start_urls = ['https://en.wikipedia.org/wiki/Main_Page/']

    rules = (
        Rule(LinkExtractor(), callback='parse_url'),
    )

    def parse_url(self, response):
        item = UrlItem()
        item['url'] = response.url

        return item

И запустить его с

scrapy crawl wiki -o wiki.csv -t csv

и вы получите URL в формате csv в файле wiki.csv.

...