[NewsSentiment] News Sentiment Analysis Part2: Text 수집


개요

News Sentiment Analysis를 위한 뉴스 기사 text를 수집합니다.

만들어둔 url db를 가지고 뉴스 기사 text를 가져와야 합니다. 필요한 라이브러리를 가져옵니다. newspaper 라이브러리는 뉴스 url을 주고 기사에서 키워드와 본문을 뽑기 위한 것입니다.

from newspaper import Article
import newspaper
from newspaper import fulltext
from newspaper.configuration import Configuration
import requests
from bs4 import BeautifulSoup
import pandas as pd
from datetime import datetime
import numpy as np
import math
import time
import calendar
import json
import sqlite3

Url db를 만들 때처럼 최신 url 데이터와 text db 데이터를 비교해서 이미 가지고 있는 text는 다운받지 않도록 최신 url 데이터만 뽑아줍니다.

con = sqlite3.connect('news_urls.db')
news_url_data = pd.read_sql('select * from news_urls', con)
news_url_data = news_url_data.loc[:, ['source','topic','title','publish_date','link']]
con.close()
# news_url_data : url_data 새로 넣어온 최신버전
# news_text_data : url 업데이트 전까지의 text가 들어가 있음 --> news_url_data에만 있고, news_text_data에는 없는 것들을 target으로
con = sqlite3.connect('news_text.db')
news_text_data = pd.read_sql('select source, topic, title, publish_date, link from news_text', con)
con.close()
# 새로 받아온 것에서 원래 db에 있는 것들을 날림
df_target = pd.merge(news_url_data, news_text_data, how='outer', indicator='Exist')
df_target = df_target.loc[df_target['Exist']=='left_only']
df_target = df_target.loc[:, ['source','topic','title','publish_date','link']]
df_target = df_target.reset_index(drop=True)

크롤링 기반이라 차단당할 수 있으니 proxy를 사용합니다.

with open('ProxyAPI.txt', 'r') as f:
    lines = f.readlines()
    api_key = lines[0].strip()

def send_request(link):
    response = requests.get(
        url="https://app.scrapingbee.com/api/v1/",
        params={
            "api_key": api_key,
            "url": link,
            "render_js": "false",
            "forward_headers": "true"
        },
        
        headers={
            "Spb-Accept-Language": "En-US",
        }
        
    )
    content = response.content
    #print('Response HTTP Status Code: ', response.status_code)
    #print('Response HTTP Response Body: ', response.content)
    return content

뉴스 url link를 받아서 뉴스의 keyword와 text를 가져옵니다. Link의 html 정보를 가져오고 parsing과 nlp 처리를 하여 키워드와 뉴스 기사 본문을 줍니다.

def extract_news(link):
    
    raw_html = send_request(link)
    article = Article('')
    article.download(raw_html)
    article.parse()
    article.nlp()
    keywords = article.keywords
    
    # 키워드를 리스트로 돌려주는데 그러면 db에 넣기가 곤란함
    # string으로 바꾸는데 //을 구분자로 넣을 것임
    keyword_str = ''
    for keyword in keywords:
        keyword_str = keyword_str + keyword + '//'
        
    text = article.text
    
    return keyword_str, text

이미 가지고 있는 text는 다운받지 않도록 최신 url 데이터만 둔 상태에서 뉴스 기사 본문 데이터를 가져옵니다.

news_text = []

for i in range(len(df_target)):
    
    print(i)
    
    try:
        # ['source','topic','title','publish_date','link']
        temp = list(np.array(df_target.loc[i].to_list()))
        
        # keyword_str, text를 temp에 append
        temp.append(extract_news(temp[4])[0])
        temp.append(extract_news(temp[4])[1])
        
        news_text.append(temp)
        
    except:
        print(temp[0], temp[1], temp[2], temp[3])
        continue
df_news_text = pd.DataFrame(news_text, columns=['source','topic','title','publish_date','link','keywords','text'])
con = sqlite3.connect('news_text.db')
df_news_text.to_sql('news_text', con, if_exists='append', index_label='id')
con.close()





© 2021.03. by JacobJinwonLee

Powered by theorydb