Python: Newspaper Module - Есть ли способ объединить получение статей прямо с URL?

Я использую модуль Newspaper для Python, найденный здесь.

В руководствах описывается, как вы можете объединить здание из разных газет, если оно генерирует их одновременно. (см. "Загрузка многопоточной статьи" в ссылке выше)

Есть ли способ сделать это для извлечения статей прямо из списка URL-адресов? То есть есть ли какой-нибудь способ, которым я могу добавить несколько URL-адресов в следующую настройку, чтобы она загружалась и анализировала их одновременно?

from newspaper import Article
url = 'http://www.bbc.co.uk/zhongwen/simp/chinese_news/2012/12/121210_hongkong_politics.shtml'
a = Article(url, language='zh') # Chinese
a.download()
a.parse()
print(a.text[:150])

3 ответа

Решение

Я смог сделать это, создав Source для каждой статьи URL. (отказ от ответственности: не разработчик Python)

import newspaper

urls = [
  'http://www.baltimorenews.net/index.php/sid/234363921',
  'http://www.baltimorenews.net/index.php/sid/234323971',
  'http://www.atlantanews.net/index.php/sid/234323891',
  'http://www.wpbf.com/news/funeral-held-for-gabby-desouza/33874572',  
]

class SingleSource(newspaper.Source):
    def __init__(self, articleURL):
        super(StubSource, self).__init__("http://localhost")
        self.articles = [newspaper.Article(url=url)]

sources = [SingleSource(articleURL=u) for u in urls]

newspaper.news_pool.set(sources)
newspaper.news_pool.join()

for s in sources:
  print s.articles[0].html

Я знаю, что этот вопрос действительно старый, но это одна из первых ссылок, которая появляется, когда я гуглю, как получить многопоточную газету. Хотя ответ Кайлса очень полезен, он неполон, и я думаю, что в нем есть некоторые опечатки...

import newspaper

urls = [
'http://www.baltimorenews.net/index.php/sid/234363921',
'http://www.baltimorenews.net/index.php/sid/234323971',
'http://www.atlantanews.net/index.php/sid/234323891',
'http://www.wpbf.com/news/funeral-held-for-gabby-desouza/33874572',  
]

class SingleSource(newspaper.Source):
def __init__(self, articleURL):
    super(SingleSource, self).__init__("http://localhost")
    self.articles = [newspaper.Article(url=articleURL)]

sources = [SingleSource(articleURL=u) for u in urls]

newspaper.news_pool.set(sources)
newspaper.news_pool.join()

Я изменил Stubsource на Singlesource и один из URL-адресов на articleURL. Конечно, это просто загружает веб-страницы, вам все еще нужно разобрать их, чтобы иметь возможность получить текст.

multi=[]
i=0
for s in sources:
    i+=1
    try:
        (s.articles[0]).parse()
        txt = (s.articles[0]).text
        multi.append(txt)
    except:
        pass

В моей выборке из 100 URL это заняло половину времени по сравнению с последовательной работой с каждым URL. (Изменить: после увеличения размера выборки до 2000, происходит сокращение примерно на четверть.)

(Правка: все работает с многопоточностью!) Я использовал это очень хорошее объяснение для своей реализации. При размере выборки в 100 URL-адресов использование 4 потоков занимает время, сопоставимое с кодом выше, но увеличение числа потоков до 10 дает дальнейшее сокращение примерно вдвое. Больший размер выборки требует большего количества потоков, чтобы дать сопоставимую разницу.

import newspaper
from multiprocessing.dummy import Pool as ThreadPool

def getTxt(url):
    article = Article(url)
    article.download()
    try:
        article.parse()
        txt=article.text
        return txt
    except:
        return ""

pool = ThreadPool(10)

# open the urls in their own threads
# and return the results
results = pool.map(getTxt, urls)

# close the pool and wait for the work to finish 
pool.close() 
pool.join()

Опираясь на ответ Джозефа Валлса. Я предполагаю, что исходный плакат хотел использовать многопоточность для извлечения кучи данных и их правильного хранения. После долгих попыток я думаю, что нашел решение, оно может быть не самым эффективным, но оно работает, однако я попытался сделать его лучше, я думаю, что плагин газета3k может быть немного глючным. Однако это работает при извлечении желаемых элементов в DataFrame.

import newspaper
from newspaper import Article
from newspaper import Source
import pandas as pd

gamespot_paper = newspaper.build('https://www.gamespot.com/news/', memoize_articles=False)
bbc_paper = newspaper.build("https://www.bbc.com/news", memoize_articles=False)
papers = [gamespot_paper, bbc_paper]
news_pool.set(papers, threads_per_source=4) 
news_pool.join()

#Create our final dataframe
df_articles = pd.DataFrame()

#Create a download limit per sources
limit = 100

for source in papers:
    #tempoary lists to store each element we want to extract
    list_title = []
    list_text = []
    list_source =[]

    count = 0

    for article_extract in source.articles:
        article_extract.parse()

        if count > limit:
            break

        #appending the elements we want to extract
        list_title.append(article_extract.title)
        list_text.append(article_extract.text)
        list_source.append(article_extract.source_url)

        #Update count
        count +=1


    df_temp = pd.DataFrame({'Title': list_title, 'Text': list_text, 'Source': list_source})
    #Append to the final DataFrame
    df_articles = df_articles.append(df_temp, ignore_index = True)
    print('source extracted')

Пожалуйста, предлагайте какие-либо улучшения!

Я не знаком с модулем "Газета", но следующий код использует список URL-адресов и должен быть эквивалентен тому, который представлен на связанной странице:

import newspaper
from newspaper import news_pool

urls = ['http://slate.com','http://techcrunch.com','http://espn.com']
papers = [newspaper.build(i) for i in urls]
news_pool.set(papers, threads_per_source=2)
news_pool.join()
Другие вопросы по тегам