【问题标题】:Write 'Function output ' into a nice Pandas dataframe将“函数输出”写入一个漂亮的 Pandas 数据框
【发布时间】:2018-01-08 15:03:51
【问题描述】:

我曾经和 spark 一起工作过,他设法自动构建漂亮的表。 现在我用python和美汤来摄取药物数据。 这是我的代码,我想建立一个包含所有药物及其相关信息的表格。

我尝试使用“split”,因为信息是用“---”分开的

但没有得到可读的东西: 请在下面找到代码+结果示例+理想DataFrame的结构

1- 代码

import requests
from bs4 import BeautifulSoup

def get_details(url):
   print('details:', url)

   # get subpage
   r = requests.get(url)
   soup = BeautifulSoup(r.text ,"lxml")

   # get data on subpabe
   dts = soup.findAll('dt')
   dds = soup.findAll('dd')

   # display details
    for dt, dd in zip(dts, dds):
        print(dt.text)
        print(dd.text)
        print('---')

        print('---------------------------')

def drug_data():
    url = 'https://www.drugbank.ca/drugs/'

    while url:
         print(url)
         r = requests.get(url)
         soup = BeautifulSoup(r.text ,"lxml")

         # get links to subpages
         links = soup.select('strong a')
         for link in links:
             # exeecute function to get subpage
             get_details('https://www.drugbank.ca' + link['href'])

        # next page url
         url = soup.findAll('a', {'class': 'page-link', 'rel': 'next'})
         print(url)
         if url:
            url = 'https://www.drugbank.ca' + url[0].get('href')
         else:
            break

2-输出结构如下:

名字

5-甲基四氢叶酸

入藏号

DB04789

类型

小分子

已获批准的营养保健品

说明 5-甲基四氢叶酸是四氢叶酸的甲基化衍生物。它是由亚甲基四氢叶酸还原酶从 5,10-亚甲基四氢叶酸中生成的,用于通过 5-甲基四氢叶酸-高半胱氨酸甲基转移酶(也称为蛋氨酸合酶)将高半胱氨酸回收回蛋氨酸。

Panda 数据框应如下所示:

你有什么建议? 最好的

【问题讨论】:

  • 请您更正代码的缩进。
  • 完成谢谢您的建议
  • 我认为你使用的是 Python 3.x 而不是 Python 2.x。

标签: python python-2.7 pandas dataframe beautifulsoup


【解决方案1】:

如果您想要对现有代码进行最简单的扩展,只为 DataFrame 选择几列,可以使用以下内容作为起点:

import requests
from bs4 import BeautifulSoup
import pandas as pd

headings=['Name','Accession Number','Type','Groups','Description']   # add more as needed, first hit on each is taken
df = pd.DataFrame([], columns=headings)   

def get_details(url):
    global df
    global headings
    print('details:', url)
    r = requests.get(url)
    soup = BeautifulSoup(r.text ,"lxml")
    dts = soup.findAll('dt')
    dds = soup.findAll('dd')
    data = {}
    for dt, dd in zip(dts, dds):
        if (dt.text in headings) and (dt.text not in data):
            data[dt.text] = dd.text
    df = df.append(data,ignore_index=True)

def drug_data():
    url = 'https://www.drugbank.ca/drugs/'    
    while url:
         print(url)
         r = requests.get(url)
         soup = BeautifulSoup(r.text ,"lxml")

         # get links to subpages
         links = soup.select('strong a')
         for link in links:
             # exeecute function to get subpage
             get_details('https://www.drugbank.ca' + link['href'])

        # next page url
         url = soup.findAll('a', {'class': 'page-link', 'rel': 'next'})
         print(url)
         if url:
            url = 'https://www.drugbank.ca' + url[0].get('href')
         else:
            break

drug_data()

print df[['Name', 'Accession Number']]

(请注意,您的网址中的数据问题是您在例如“描述”上获得了多次点击)无论如何,希望这可能会有所帮助。

【讨论】:

  • 非常感谢,但我获得了一个空数据框:空数据框列:[名称,入藏号]索引:[]
  • @Lizou 尝试只在一个页面上运行代码(有 2500 多个,太长了无法测试所有内容),但我从第 1 页得到了 24 种药物...
【解决方案2】:

要实现我们的目标,需要做一些事情。首先,您必须将解析后的 H​​TML 文件转换为 Pandas Dataframes。为此,您可以使用 Pandas read_html 函数。然后,您必须将每个生成的 Pandas Dataframes 合并到一个 Dataframe 中。 要设置输出的样式,您可以使用 Pandas 显示相关选项,因为这在一定程度上取决于您的系统,我只是在脚本顶部放置了三个可能的选项。欢迎咨询Pandas options了解更多配置。

### Load the pandas library
import pandas as pd

### Set Pandas settings

# Set max number of displayed columns
pd.set_option('display.max_columns', 100)

# Set max column width
pd.set_option('display.max_colwidth', 1000)

# Prevent pandas linebreak
pd.set_option('display.expand_frame_repr', False)

import requests
from bs4 import BeautifulSoup

def get_details(url):
    print('details:', url)

    # get subpage
    r = requests.get(url)
    soup = BeautifulSoup(r.text ,"lxml")

    ### Convert the soup object to string 
    #   than you can parse it directly with pandas
    #   this returns a list of dfs therefore, fetch the first list item
    #   return the df to merge it later with the other results
    return pd.read_html(str(soup))[0]


def drug_data():
    url = 'https://www.drugbank.ca/drugs/'

    ### Helper list to store the single drugs Pandas Dataframes
    listOfDrugDfs = []

    while url:

        print(url)
        r = requests.get(url)
        soup = BeautifulSoup(r.text ,"lxml")

        # get links to subpages
        links = soup.select('strong a')
        for link in links:

            # exeecute function to get subpage
            ### Extended to append results of function to listOfDrugDfs
            listOfDrugDfs.append(get_details('https://www.drugbank.ca' + link['href']))

        # next page url
        url = soup.findAll('a', {'class': 'page-link', 'rel': 'next'})
        print(url)
        if url:
            url = 'https://www.drugbank.ca' + url[0].get('href')
        else:
            break

    ### Merge single results dfs to one big results dataframe
    resultDf = pd.concat(listOfDrugDfs)

    ### Print results
    print(resultDf)

    ### Or return
    #return resultDf

【讨论】:

  • 您是否尝试过执行您的提案? @asamoah
  • 是的,我做到了。它运行没有任何错误和正确的结果。你有任何错误吗?
  • 没问题!!百万谢谢!我希望这个讨论对其他人有帮助:)
猜你喜欢
  • 2015-10-31
  • 2016-08-13
  • 2016-11-13
  • 2021-01-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-02-17
  • 1970-01-01
相关资源
最近更新 更多