WGET - 仅使用一个HTTP请求从同一源获取多个XPath

时间:2017-09-14 02:51:40

标签: xml bash shell xpath wget

我需要解析HTML表及其“标题”。这两个都包含在同一个URL中。这就是我到目前为止所做的:

#!/bin/bash

name_query="html/body/div[3]/div/div[1]/div[3]/div[1]/h1/text()"

# Use xargs to TRIM result.
header=$(wget -O - "https://example.com/section-1/name-1/financial-data/" |
    xmllint --html --xpath "$name_query" - 2>/dev/null |
    xargs)

wget -O - "https://example.com/section-1/name-1/financial-data/" |
    xmllint --html --xpath '//*[@id="financial-data"]/div/table/tbody' - 2>/dev/null |
    xmlstarlet ed --subnode "/tbody/tr" --type elem -n td -v "$header" >> /Applications/parser/output.txt

这会产生两个请求:

  1. 获取名称并将其传递给变量$header
  2. 获取表格并附加子节点<td>$header</td>
  3. 因此,这会将以下内容写入我的 output.txt 文件:

    <tbody>
    
                        <tr class="text-right">
                          <td class="text-left">Sep 08, 2017</td>
                          <td>4605.16</td>     
                          <td>4661.00</td>
                          <td>4075.18</td>
                          <td>4228.75</td>
                          <td>2,700,890,000</td>
                          <td>76,220,200,000</td>
                          <td>Name 1</td>
                        </tr>
    
                        <tr class="text-right">
                          <td class="text-left">Sep 07, 2017</td>
                          <td>4589.14</td>     
                          <td>4655.04</td>
                          <td>4491.33</td>
                          <td>4599.88</td>
                          <td>1,844,620,000</td>
                          <td>75,945,000,000</td>
                          <td>Name 1</td>
                        </tr>
    ...
    </tbody>
    

    它相对较慢而且效率低下,因为它实际上会产生两次相同的请求。我相信这只能通过一个请求来完成。

    我正在寻找类似的东西:

    #!/bin/bash
    
    name_query="html/body/div[3]/div/div[1]/div[3]/div[1]/h1/text()"
    
    content=$(wget -O - "https://example.com/section-1/name-1/financial-data/")
    
    # Use xargs to TRIM result.
    header=$($content | xmllint --html --xpath "$name_query" - 2>/dev/null | xargs)
    
    $content | 
        xmllint --html --xpath '//*[@id="financial-data"]/div/table/tbody' - 2>/dev/null |
        xmlstarlet ed --subnode "/tbody/tr" --type elem -n td -v "$header" >> /Applications/parser/output.txt
    

    这不起作用并产生以下错误:

    ./test: line 8: <!DOCTYPE: command not found
    ./test: line 10: <!DOCTYPE: command not found
    -:1.1: Document is empty
    

    确实,输出文件为空。我无法弄清楚原因。

    替代答案

    另一种解决方法是使用herestring

    #!/bin/bash
    
    title_query="html/body/div[3]/div/div[1]/div[3]/div[1]/h1/text()"
    
    content=$(wget -O - "https://coinmarketcap.com/currencies/bitcoin/historical-data/")
    
    # Use xargs to TRIM result.
    header=$(xmllint --html --xpath "$title_query" - <<<"$content" 2>/dev/null | xargs)
    
    xmllint --html --xpath '//*[@id="financial-data"]/div/table/tbody' - <<<"$content" 2>/dev/null |
        xmlstarlet ed --subnode "/tbody/tr" --type elem -n td -v "$header" >> /Applications/parser/output.txt
    

    <<<"$content"也对我有用。

1 个答案:

答案 0 :(得分:1)

你忘了告诉bash你用$ content var。

做了什么

bash认为你在$ content中拥有的是命令

使用

echo $content | ....