【问题标题】:web scrape nested text features网页抓取嵌套文本功能
【发布时间】:2017-08-02 13:51:45
【问题描述】:

我正在尝试为在线绘图的轴以及与之相关的一些功能(例如文本的颜色)抓取文本,但很少使用抓取,因此非常感谢您的帮助。对于经常使用刮板的人来说,这可能是一个简单的解决方法。这是我的代码:

from bs4 import BeautifulSoup
import requests

def get_IPF_transcriptome_groups():

url = "https://research.cchmc.org/pbge/lunggens/lungDisease/celltype_IPF.html?cid=1"
r = requests.get(url)
data=r.text
soup = BeautifulSoup(data)


for d in soup.find('div', attrs={'id':'wrapper'}).find(
        'div', attrs={'class':'content'}).find(
                'div', attrs={'id':'ResPanel'}).find(
                        'table', attrs={'id':'maintable'}).find(
                                'tbody'):
    print(d)

我收到一个错误:

    'tbody'):

    TypeError: 'NoneType' object is not iterable

我认为代码无法通过表体。我要解析的实际文本通过其他几个标签(包括“div”、“td”、“tr”、“g”等)隐藏得更深一些,如下所示:

<tspan style="fill:#006600;font-size:7px;">CC002_33_N709_S503_C10</tspan>

其中“CC002_33_N709_S503_C10”是示例参考,“#006600”是指颜色。有(我认为)540行这样的。如果有人可以提供帮助,那真的很棒吗?非常感谢

根据 Uday 的回复进行编辑:

感谢您的建议,我已经在其中内置了“findAll”并使用索引来检索下一个片段。这个建议here 提到删除“tbody”标签,因为它可能不是源代码的一部分。只是添加'tspan'似乎并没有返回我需要的东西。这是我更新的代码:

    for d in soup.find('div', attrs={'id':'wrapper'}).find(
        'div', attrs={'class':'content'}).find(
                'div', attrs={'id':'ResPanel'}).find(
                        'table', attrs={'id':'maintable'}).findAll(
                                'tr')[2].findAll('td')[0].find('div', attrs={'id':'sigheatmapcontainer'}): 
                                        print(d)

任何进一步的建议会真的很有帮助吗?

【问题讨论】:

  • 错误 TypeError: 'NoneType' object is not iterable 表示最终返回的对象 (find( 'tbody')) 不是运行 for 循环的列表。尝试使用find_all('tbody') 获取表格内容。我想你可能需要find('tbody').find_all('tspan')
  • 代码运行没有崩溃到'sigheatmapcontainer',但似乎是空的,如果我尝试找到下一个div:.find('div', attrs={'id':'highcharts -40'}) 然后它返回 TypeError: 'NoneType' object is not iterable

标签: python beautifulsoup


【解决方案1】:

您想要的数据是通过 JavaScript 使用 POST 请求从另一个 URL 获取的。 (它不在此网页页面的源代码 (HTML) 中,甚至不会使用 Dryscrape 进行渲染。)它以 JSON 格式返回,这很好且易于解析。以下代码将获取所有数据。如何解释数据是另一个问题,但也许你比我更清楚。

from bs4 import BeautifulSoup
import requests
import json
# Fetch the data.
url = "https://research.cchmc.org/pbge/lunggens/celltypeIPF"
r = requests.post(url, data = {'id':'1'})
data=r.text
soup = BeautifulSoup(data, "lxml")
d = soup.find('p')
# now you have the json containing all the data.
jn = json.loads(d.text)
print(json.dumps(jn, indent=2))

输出漂亮打印的原始数据。

您可以按照您想要的方式解析 JSON,例如如果你喜欢熊猫

from pandas.io.json import json_normalize
import pandas as pd
...
df = pd.DataFrame(json_normalize(jn))

【讨论】:

  • 非常感谢您对此的见解,它肯定会解析出相关数据。你介意解释一些代码吗?例如“requests.post(url, data = {'id':'1'})”与我最初使用的“requests.get(url)”不同?大概这会将数据构造成类似字典的格式?另外,你怎么知道数据是通过 JavaScript 的 POST 请求从另一个 URL 获取的? html中有什么东西表明了这一点吗?最后;文本颜色在 x 轴上发生变化,我认为它以某种方式由“df['celltypecnt'][0]”中的数据定义,但不确定?
  • 在您的原始 URL 中,您有一个查询字符串 ?cid=1 JavaScript 发送了一个带有 {'id':'1'} 的 POST 请求,是的,POST 数据是一个类似字典的结构,但它是在 HTTP 请求中。我使用“Live Headers”检查了请求,以查看幕后发生的事情以找到 POST 请求。我无法解释您需要以某种方式关联它的数据或检查呈现它的 JavaScript,所以我不知道 X 轴上的颜色是什么。
  • 太好了,非常感谢您的帮助,我将进一步阅读查询字符串和实时标题。
猜你喜欢
  • 2018-02-04
  • 2014-05-11
  • 1970-01-01
  • 2010-09-29
  • 1970-01-01
  • 1970-01-01
  • 2022-01-21
  • 1970-01-01
  • 2019-11-05
相关资源
最近更新 更多