【问题标题】:Not able to extract data or find problem with code无法提取数据或发现代码问题
【发布时间】:2021-11-13 20:11:17
【问题描述】:

以下是从 Google 新闻中提取不同公司新闻文章的代码。这给了我一个只有标题的空 excel 文件。我无法弄清楚错误是什么。有人可以帮忙吗。 (整个代码可以复制粘贴,并在您的机器上复制):

import requests
import random 
from collections import OrderedDict
def list_header():
  headers_list = [
        # Firefox 24 Linux
        {
            'User-Agent': 'Mozilla/5.0 (X11; Ubuntu; Linux i686; rv:24.0) Gecko/20100101 Firefox/24.0',
            'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',
            'Accept-Language': 'en-US,en;q=0.5',
            'DNT': '1',
            'Connection': 'keep-alive',
            'Upgrade-Insecure-Requests': '1',
        },
        # Firefox Mac
        {
            'User-Agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_5) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/13.1.1 Safari/605.1.15',
            'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',
            'Accept-Language': 'en-US,en;q=0.5',
            'DNT': '1',
            'Connection': 'keep-alive',
            'Upgrade-Insecure-Requests': '1',
        }]

  return headers_list
def list_dict():
    # Get headers list
    headers_list = list_header()
    # Create ordered dict from Headers above
    ordered_headers_list = []
    for headers in headers_list:
        h = OrderedDict()
        for header,value in headers.items():
            h[header]=value
        ordered_headers_list.append(h)
    return ordered_headers_list
def list_test():
    headers_list = list_dict()
    max = len(headers_list)
    url = 'https://httpbin.org/headers'
    for i in range(0,max):
        #Pick a random browser headers
        headers = random.choice(headers_list)
        #Create a request session
        r = requests.Session()
        r.headers = headers
        
        response = r.get(url)
        print("Request #%d\nUser-Agent Sent:%s\n\nHeaders Recevied by HTTPBin:"%(i,headers['User-Agent']))
        print(response.json())
        print("-------------------")
def random_header():
    headers_list = list_dict()
    headers = random.choice(headers_list)
    return headers
import pandas as pd
def ingest_google_news():
    ticker_list = ['AAPL.O', 'MSFT', 'GOOG', '2222.SR', 'AMZN', 'FB', 'TSLA', 'BRK-A', 'TCEHY', 'TSM', 'NVDA', 'JPM', 'BABA', 'V', 'JNJ', '005930.KS', 'WMT', 'LVMUY']

    sep = '.'
    
    df = pd.DataFrame()
    t_news = []
    t_publisher = []
    t_urls = []
    t_dates = []
    t_tickers = []

    for t in ticker_list:
        news = []
        publisher = []
        urls = []
        dates = []
        tickers = []

        # cleaning ticker
        ticker = t
        t = t.split(sep, 1)[0]

        # set header by random user agent 
        r = requests.Session()
        headers = random_header()
        r.headers = headers
        # print(headers)

        # set query for google
        query = '{} news'.format(t)
        url = f"https://www.google.com/search?q={query}&tbm=nws&lr=lang_en&hl=en&sort=date&num=5"
        res = r.get(url, headers=headers)
        soup = bs4.BeautifulSoup(res.text, "html.parser")
        
        links = soup.select(".dbsr a")
        for l in links:
            tickers.append(t)
            try:
                url_w = l.get("href")
                print(url_w)
                urls.append(url_w)
                dt = find_date(url_w)
                dates.append(dt)

                res = requests.get(url_w, headers=headers)
                parsed_article = bs4.BeautifulSoup(res.text,'lxml')
                paragraphs = parsed_article.find_all('p')

                article_text = ""
                for p in paragraphs:
                    article_text += p.text

            except Exception as e:
                article_text = ''

            news.append(article_text)

        sources = soup.select(".XTjFC g-img")
        for s in sources:
            publisher.append(s.next_sibling.lower())

        t_urls += urls
        t_news += news
        t_publisher += publisher
        t_dates += dates
        t_tickers += tickers

    df['ticker'] = t_tickers
    df['links'] = t_urls
    df['article_text'] = t_news
    df['publisher'] = t_publisher
    df['created_at'] = t_dates

    # import to csv
    today = datetime.date.today()
    d1 = today.strftime("%d%m%Y")
    df.to_csv(f'/content/drive/MyDrive/google_news_{d1}.csv')

    del news, publisher, urls, dates, tickers
    del t_news, t_publisher, t_urls, t_dates, t_tickers
import bs4
from bs4 import BeautifulSoup  
import datetime
ingest_google_news()

以上代码来自以下链接:https://medium.com/analytics-vidhya/google-scraping-using-beautifulsoup-d53746ef5a32

【问题讨论】:

  • 为了帮助解决错误,请发布错误。

标签: python dataframe web-scraping beautifulsoup


【解决方案1】:

查看SelectorGadget Chrome 扩展程序,通过在浏览器中单击所需元素来获取CSS 选择器。 CSS 选择器 reference.

代码和example in the online IDE(提取标题、链接、sn-p、发布日期、来源,并存储到CSV):

from bs4 import BeautifulSoup
import requests, lxml

headers = {
    "User-Agent":
    "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.102 Safari/537.36 Edge/18.19582"
}

ticker_list = ['AAPL.O', 'LVS', 'COTY.K','JPM', 'XOM', '005930.KS']

def get_news():

    # iterate over each ticker 
    for news in ticker_list:
        params = {
            "q": news,     # query
            "hl": "en",    # language
            "gl": "us",    # country to search from
            "tbm": "nws",  # google news filter
        }

        # store news data
        news_data = []

        html = requests.get('https://www.google.com/search', headers=headers, params=params)
        soup = BeautifulSoup(html.text, 'lxml')
        
        # container with needed data
        for result in soup.select('.WlydOe'):
            title = result.select_one('.nDgy9d').text
            link = result['href']
            source = result.select_one('.CEMjEf span').text
            snippet = result.select_one('.GI74Re').text
            date_published = result.select_one('p.S1FAPd').text
            
            print(f'{title}\n{link}\n{snippet}\n{date_published}\n{source}\n')
            
            # append news data to list in dict() format to save it later via pandas
            news_data.append({
              'title': title,
              'link': link,
              'snippet': snippet,
              'date_published': date_published,
              'source': source
            })

        # create DataFrame from the list()
        df = pd.DataFrame(news_data)

        # save DataFrame to csv without default index column on the left side
        df.to_csv('bs4_final.csv', index=False)


get_news()


----------
'''
EU plans to legislate for common phone charger despite ...
https://www.reuters.com/technology/eu-plans-legislate-common-phone-charger-despite-apple-grumbles-2021-09-21/
... a person familiar with the matter said - a move likely to affect iPhone 
maker Apple (AAPL.O) more than its rivals.
2 hours ago
Reuters

Wall Street ends sharply lower in broad sell-off
https://www.reuters.com/business/wall-street-ends-sharply-lower-broad-sell-off-2021-09-20/
O), Amazon.com Inc (AMZN.O), Apple Inc (AAPL.O), Facebook Inc (FB. ... O) 
were among the biggest drags on the index as well as the S&P 500.
18 hours ago
Reuters

... other results
'''

或者,您可以使用来自 SerpApi 的 Google News Results API 来实现相同的目的。这是一个带有免费计划的付费 API。

您的示例的主要区别在于,您无需将事情弄得那么复杂,弄清楚为什么事情不能按预期工作,然后随着时间的推移对其进行维护。相反,您只需要迭代结构化 JSON 并快速获得所需内容。

要集成的代码(保存到 csv 的过程与上面的代码相同):

import os
from serpapi import GoogleSearch

ticker_list = ['AAPL.O', 'LVS', 'COTY.K','JPM', 'XOM', '005930.KS']

def get_news():

    for news in ticker_list:  
        params = {
          "engine": "google",
          "q": news,
          "gl": "us",
          "tbm": "nws",
          "api_key": os.getenv("API_KEY"),   # API environment variable
        }

        search = GoogleSearch(params)
        results = search.get_dict()

        for news_result in results["news_results"]:
          print(f"Title: {news_result['title']}\nLink: {news_result['link']}\n")


get_news()

-----------
'''
Title: EU plans to legislate for common phone charger despite ...
Link: https://www.reuters.com/technology/eu-plans-legislate-common-phone-charger-despite-apple-grumbles-2021-09-21/

Title: Wall Street ends sharply lower in broad sell-off
Link: https://www.reuters.com/business/wall-street-ends-sharply-lower-broad-sell-off-2021-09-20/

Title: S&P 500 down more than 2% as growth worries rise
Link: https://www.reuters.com/business/sp-500-down-more-than-2-growth-worries-rise-2021-09-20/

Title: Apple joins streaming elite, Netflix crosses milestone with ...
Link: https://www.reuters.com/technology/apple-joins-streaming-elite-netflix-crosses-milestone-with-emmy-wins-2021-09-20/

... other results
'''

免责声明,我为 SerpApi 工作。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-02-17
    • 2021-11-24
    • 2020-10-05
    • 2020-09-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多