【问题标题】:Beautiful soup get text for multiple pages美丽的汤获得多页的文字
【发布时间】:2018-09-04 09:34:22
【问题描述】:

我尝试抓取德国政党的新闻页面并将所有信息存储在数据框中(“python 初学者”)。当我想将整个文本甚至日期存储到数据框中时,只存在一个小问题。似乎只有文本的最后一个元素 (p ... /p) 将存储在行中。我认为问题的出现是因为循环上的迭代具有误导性。

import pandas as pd
import requests 
from time import sleep
from random import randint
from time import time
import numpy as np
from urllib.request import urlopen

data = pd.DataFrame()
teaser = ()
title = []
content = ()
childrenUrls = []
mainPage = "https://www.fdp.de"
start_time = time()
counter = 0

#for i in list(map(lambda x: x+1, range(3))):
for i in range(3):

    counter = counter + 1
    sleep(randint(1,3))
    elapsed_time = time() - start_time
    print('Request: {}; Frequency: {} requests/s'.format(counter, counter/elapsed_time))
    url = "https://www.fdp.de/seite/aktuelles?page="+str(i)
    #print(url)
    r = requests.get(url)
    soup = BeautifulSoup(r.content, 'html.parser')

    uls = soup.find_all('div', {'class': 'field-title'})

    for ul in uls:
        for li in ul.find_all('h2'):
            for link in li.find_all('a'):
                url = link.get('href')
                contents = link.text
                print(contents)
                childrenUrls = mainPage+url
                print(childrenUrls)

                childrenPages = urllib2.urlopen(childrenUrls)
                soupCP = BeautifulSoup(childrenPages, 'html.parser')

                #content1 = soupCP.findAll('p').get_text()
                #print(content1)

                for content in soupCP.findAll('p'):
                    #for message in content.get('p'):
                    content = content.text.strip()
                    print(content)

                for teaser in soupCP.find_all('div', class_ = 'field-teaser'):
                    teaser = teaser.text.strip()
                    print(date)

                for title in soupCP.find_all('title'):
                    title = title.text.strip()
                    print(ttt)

                df = pd.DataFrame(
                    {'teaser': teaser,
                     'title' : title,
                    'content' : content}, index=[counter])

                data = pd.concat([data, df])
    #join(str(v) for v in value_list)

【问题讨论】:

    标签: python pandas loops for-loop beautifulsoup


    【解决方案1】:

    您必须将每个循环中的文本保存在一个列表中,而不是保存在一个简单的字符串变量中。在每次迭代中,您的代码都会重新定义变量的值;这会导致丢失以前的数据。

    一个好的方法是在这里使用list comprehension。将代码的最后 3 个 for 循环替换为:

    content = [x.text.strip() for x in soupCP.find_all('p')]
    teaser = [x.text.strip() for x in soupCP.find_all('div', class_='field-teaser')]
    title = [x.text.strip() for x in soupCP.find_all('title')]
    
    df = pd.DataFrame(
        {'teaser': teaser,
         'title': title,
         'content': content}, index=[counter])
    
    data = pd.concat([data, df])
    

    列表推导式的简单解释

    content = [x.text.strip() for x in soupCP.find_all('p')] 行相当于:

    content = []
    for x in soupCP.find_all('p'):
        content.append(x.text.strip())
    

    【讨论】:

    • 好的,非常感谢您的帮助!我用您的建议替换了我的代码,但出现了另一个问题,这可能与数据帧的索引或数组有关。这是显示的错误代码:ValueError: Shape of passed values is (3, 5), indices imply (3, 1)
    • 看看这个question。我认为您必须将 .concat 替换为 .join
    • 如果关于 SO 的解决方案都不起作用,我认为您应该提出一个新问题。这个问题是关于BeautifulSoup 的问题(已解决),新问题是关于pandas。如果需要,您可以将此问题链接到另一个问题。我对pandas 没有太多经验,如果您针对该问题提出新问题,您会从其他人那里得到更好的答案。
    猜你喜欢
    • 2011-11-15
    • 1970-01-01
    • 1970-01-01
    • 2018-09-24
    • 1970-01-01
    • 2019-04-14
    • 1970-01-01
    • 2021-01-15
    • 1970-01-01
    相关资源
    最近更新 更多