Разбор красивый суп через список URL - PullRequest
0 голосов
/ 12 мая 2019

Мне нужно удалить все заголовки по теме аутизма из архива газеты Le Monde (с 1980 года).Я не программист, но гуманитарий, который пытается быть «цифровым» ...

Мне удалось получить список всех (ежедневных) проблем и, с другой стороны, проанализировать с супом один URL ввремя и извлечение заголовков работает также.Но оба вместе нет.Я заполняю свою проблему на шаге парсинга + итерации, но не могу ее решить.

from bs4 import BeautifulSoup
import requests
import re
from datetime import date, timedelta

start = date(2018, 1, 1)
end = date.today()
all_url =[]

#this chunk is working and returns a nice list of all url of all issues
day = timedelta(days=1)
one_url = "https://www.lemonde.fr/archives-du-monde/"
mydate = start

while mydate < end:
    mydate += day
    if one_url not in all_url:
        all_url.append(one_url + "{date.day:02}/{date.month:02}/{date.year}".format(date=mydate) + '/')

#this function is working as well when applied with one single url
def titles(all_url):

    for url in all_url:
        page = BeautifulSoup(requests.get(url).text, "lxml")

        regexp = re.compile(r'^.*\b(autisme|Autisme)\b.*$')

        for headlines in page.find_all("h3"):
            h = headlines.text

            for m in regexp.finditer(h):
                print(m.group())

titles(all_url)

Этот скрипт просто застрял ...

Ответы [ 2 ]

1 голос
/ 12 мая 2019

Скрипт не застрял. Я добавил операторы печати, чтобы вы могли визуализировать, что он работает. Но сначала я подумал, что проблема в вашем шаблоне регулярных выражений.

Когда я действительно открыл одну из этих веб-ссылок (https://www.lemonde.fr/archives-du-monde/25/03/2018/),, сервер ответил 404, так как эта страница не существует на сервере. enter image description here Поскольку вы создали URL-адреса страниц с кодом, поэтому весьма вероятно, что эти ссылки не соответствуют ни одной на стороне сервера.

from bs4 import BeautifulSoup
import requests
import re
from datetime import date, timedelta

start = date(2018, 1, 1)
end = date.today()
all_url =[]

#this chunk is working and returns a nice list of all url of all issues
day = timedelta(days=1)
one_url = "https://www.lemonde.fr/archives-du-monde/"
mydate = start

while mydate < end:
    mydate += day
    if one_url not in all_url:
        all_url.append(one_url + "{date.day:02}/{date.month:02}/{date.year}".format(date=mydate) + '/')

#this function is working as well when applied with one single url
def titles(all_url):

    counter = 0
    for url in all_url:
        print("[+] (" + str(counter) + ") Fetching URL " + url)
        counter += 1
        page = BeautifulSoup(requests.get(url).text, "lxml")

        regexp = re.compile(r'^.*\b(autisme|Autisme)\b.*$')

        found = False
        for headlines in page.find_all("h3"):
            h = headlines.text

            for m in regexp.finditer(h):
                found = True
                print(m.group())

        if not found:
            print("[-] Can't Find any thing relevant this page....")
            print()

titles(all_url)

Вывод скрипта:

[+] (0) Fetching URL https://www.lemonde.fr/archives-du-monde/02/01/2018/
[-] Can't Find any thing relevant this page....

[+] (1) Fetching URL https://www.lemonde.fr/archives-du-monde/03/01/2018/
[-] Can't Find any thing relevant this page....

[+] (2) Fetching URL https://www.lemonde.fr/archives-du-monde/04/01/2018/
[-] Can't Find any thing relevant this page....

[+] (3) Fetching URL https://www.lemonde.fr/archives-du-monde/05/01/2018/
[-] Can't Find any thing relevant this page....

[+] (4) Fetching URL https://www.lemonde.fr/archives-du-monde/06/01/2018/
[-] Can't Find any thing relevant this page....

[+] (5) Fetching URL https://www.lemonde.fr/archives-du-monde/07/01/2018/
[-] Can't Find any thing relevant this page....

[+] (6) Fetching URL https://www.lemonde.fr/archives-du-monde/08/01/2018/
[-] Can't Find any thing relevant this page....

[+] (7) Fetching URL https://www.lemonde.fr/archives-du-monde/09/01/2018/
[-] Can't Find any thing relevant this page....

[+] (8) Fetching URL https://www.lemonde.fr/archives-du-monde/10/01/2018/
[-] Can't Find any thing relevant this page....

[+] (9) Fetching URL https://www.lemonde.fr/archives-du-monde/11/01/2018/
[-] Can't Find any thing relevant this page....

[+] (10) Fetching URL https://www.lemonde.fr/archives-du-monde/12/01/2018/
[-] Can't Find any thing relevant this page....

Вы можете увидеть каждый URL, проверив в веб-браузерах. Пожалуйста, дайте мне знать, если вам нужна дополнительная помощь.

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

Основная проблема заключается в том, что формат даты, используемый в архивных URL-адресах Le Monde, равен day-month-year, а не day/month/year. Чтобы исправить это изменение:

all_url.append(one_url + "{date.day:02}/{date.month:02}/{date.year}".format(date=mydate) + '/')

до

all_url.append(one_url + "{date.day:02}-{date.month:02}-{date.year}".format(date=mydate) + '/')

Ощущение, что программа зависла, просто из-за отсутствия обратной связи. @ Ответ Заида показывает, как решить эту проблему элегантным образом.

Если вам нужен более быстрый подход к выполнению набора HTTP-запросов, вам следует рассмотреть возможность использования чего-то асинхронного. Я предлагаю использовать Scrapy, который является платформой, созданной для такого рода задач (утилизация в сети).

Я сделал простого паука для извлечения всех заголовков, содержащих 'autism' в архиве (с начала 2018 года и до сегодняшнего дня):

import re
from datetime import date
from datetime import timedelta

import scrapy

BASE_URL = 'https://www.lemonde.fr/archives-du-monde/'


def date_range(start, stop):
    for d in range((stop - start).days):
        yield start + timedelta(days=d)


class LeMonde(scrapy.Spider):
    name = 'LeMonde'

    def start_requests(self):
        for day in date_range(date(2018, 1, 1), date.today()):
            url = BASE_URL + '{d.day:02}-{d.month:02}-{d.year}'.format(d=day) + '/'
            yield scrapy.Request(url)

    def parse(self, response):
        for headline in response.xpath('//h3/a/text()').getall():
            headline = headline.strip()

            if 'autism' in headline.lower():
                yield { 'headline': headline }

Мне удалось удалить заголовки за 47 секунд, используя приведенный выше код. Если вы заинтересованы, вы можете запустить его с:

scrapy runspider spider_file.py -o headlines.csv

это создаст CSV-файл (headlines.csv), содержащий заголовки.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...