【问题标题】:How to scrape data from specified tag with Enlive?如何使用 Enlive 从指定标签中抓取数据?
【发布时间】:2011-10-19 20:32:31
【问题描述】:

谁能解释我如何从<th> 具有内容值的<td> 标签中抓取内容(实际上在这种情况下,我需要<b> 标签的内容进行匹配操作)“Row1 标题”,但不抓取@ 987654324@ 标签(或其任何内容)正在处理中?这是我的测试 HTML:

<table class="table_class"> 
                    <tbody> 
                       <tr> 
                         <th>
                           <b>
                              Row1 title
                           </b>
                         </th> 
                         <td>2.660.784</td> 
                         <td>2.944.552</td> 
                         <td>Correct, has 3 td elements</td> 
                       </tr> 
                       <tr> 
                         <th>                                
                              Row2 title                                
                          </th> 
                         <td>2.660.784</td> 
                         <td>2.944.552</td> 
                         <td>Correct, has 3 td elements</td> 
                       </tr> 
                    </tbody>
</table>

我要提取的数据应该来自这些标签:

                     <td>2.660.784</td> 
                     <td>2.944.552</td> 
                     <td>Correct, has 3 td elements</td> 

我设法创建了返回表的全部内容的函数,但我想从结果中排除 &lt;th&gt; 节点,并只返回来自 &lt;td&gt; 节点的数据,我可以使用这些内容进行进一步解析.谁能帮我解决这个问题?

【问题讨论】:

    标签: clojure screen-scraping enlive


    【解决方案1】:

    有了这样的活动

    (ns tutorial.so-scrape
      (:require [net.cgrand.enlive-html :as html])
    
    (defn parse-tds [url] 
     (html/select (html/html-resource (java.net.URL. url)) [:table :td])) 
    

    应该为您提供所有td 节点的序列,格式为{:tag :td :attrs {...} :content (...)}。我不知道 enlive 可以让您直接获取这些节点的内容。我可能是错的。

    然后您可以提取序列的内容以获取类似于
    (for [line ws-content] (apply str (:content line)))

    的内容

    关于question you posted yesterday(我假设您仍在使用该页面) - 我在那里给出的解决方案有点复杂 - 但它也很灵活。例如,如果您像这样更改tag-type 函数

    (defn tag-type [node]
      (case (:tag node) 
       :td    ::TerminalNode
       ::IgnoreNode)
    

    (将所有节点的返回值更改为::IgnoreNode:td 除外,那么它只会为您提供:tds 的内容序列,这可能与您想要的很接近。如果您告诉我需要更多帮助。

    EDIT(回复下面的 cmets) 我认为仅使用 enlive 无法根据 :content 选择节点 - 但您当然可以使用 Clojure 这样做。

    例如,你可以做类似的事情

    (for [line ws-content :when (re-find (re-pattern "WHAT YOU WANT TO MATCH") (:content line))]
      (:content line))
    

    可以工作。 (您可能需要稍微调整一下(:content line) 表单......

    【讨论】:

    • (伪代码)(map #(html/select % [[:th :b ("WHERE :CONTENT OF :b tag is equal to "UKUPNA AKTIVA")]]) (remove nil? (map get-data-balance_sheet (h3+table "http://www.belex.rs/trgovanje/prospekt/VZAS/show")))) 我得到(()),但如果只有 th 站在那里,我会得到表中所有 th 元素的序列。我只想要一个具有&lt;b&gt; 元素且内容为“UKUPNA AKTIVA”的元素。我将尝试使用此结果来获取在他之后的&lt;td&gt;nodes。
    • 我要跳到的结果是 元素序列,其中 th 标签(或者在我的情况下是 b 标签)具有指定值。
    • 我不认为仅使用 enlive 就可以实现您想要的 - 它根据节点 id 和类而不是它们的内容来选择节点(据我所知)。但是您当然可以使用 Clojure 执行此操作 - 我看不出您不这样做的原因(请参阅答案更改)。
    • 您发布的编辑对我来说非常有用。与此同时,我设法编写了一些代码,这使我能够做到同样的事情,但你的更优雅。这是我的代码(或者准确地说是重型 hack):(apply str (flatten (map :content (flatten (map #(html/select % [:th :b]) (remove nil? (map get-data-balance_sheet (h3+table "http://www.belex.rs/trgovanje/prospekt/VZAS/show"))))))))
    • 嗯,另一方面,你的要短得多;)祝你好运,玩 clojure!
    猜你喜欢
    相关资源
    最近更新 更多
    热门标签