如何使用 LibreOffice 的 Calc 从网站获取数据?

DMT*_*DMT 3 libreoffice-calc

我正在寻找一种使用 LibreOffice 的 Calc 从网站获取一些数据的方法。

我之前使用 Google Sheets 和 IMPORTXML 函数,但因为它非常不可靠,所以我想改用 Calc。

我的功能如下所示:

=IMPORTXML(E2; "//h3[@class='产品名称']")

=IMPORTXML(E2; "//span[@class='price']")

正如您已经猜到的,URL 位于 E2 中(fi http://www.killis.at/gin/monkey-47-gin-distiller-s-cut-2016-0-5-lt.html)。

在 Calc 中,我=FILTERXML(WEBSERVICE(E2);"//h3[@class='product-name']")只尝试得到#VALUE!结果。

我的 LibreOffice 版本是 6.0.4.2,带有德语区域设置。我使用带有“;”的英文函数名称 作为分隔符。

那么 Calc 中这个函数的等价物是什么?产品名称和价格的适当命令是什么样的?

Axe*_*ter 6

问题是,虽然IMPORTXML声称能够解析标签汤 HTML(并非在所有情况下都是如此),但 FILTERXML每个定义都需要一个有效的 XML 流。并且标签 soup HTML 不是有效的 XML 流。老实说,HTML 大多数情况下与有效的 XML 流相反。

因此,唯一的方法是使用第三方标签 soup 解析器或将 HTML 标签 soup 作为字符串并使用字符串操作来查找字符串中所需的部分。

第二种方法可能如下所示:

Public Function GETFROMHTML(sURL as String, sStartTag as String) as String

   on error goto onErrorExit
   oSimpleFileAccess = createUNOService ("com.sun.star.ucb.SimpleFileAccess")
   oInpDataStream = createUNOService ("com.sun.star.io.TextInputStream")
   oInpDataStream.setInputStream(oSimpleFileAccess.openFileRead(sUrl))
   dim delimiters() as long
   sContent = oInpDataStream.readString(delimiters(), false)

   lStartPos = instr(1, sContent, sStartTag )
   if lStartPos = 0 then
     GETFROMHTML = "tag " & sStartTag & " not found"
     exit function
   end if   
   lEndPos = instr(lStartPos, sContent, "</")
   lStartPos = lStartPos + 1 + len(sStartTag)
   sText = trim(replace(replace(mid(sContent, lStartPos, lEndPos-lStartPos), chr(10), ""), chr(13), ""))
   GETFROMHTML = sText

 onErrorExit:
   on error goto 0
End Function
Run Code Online (Sandbox Code Playgroud)

在 Calc 单元中使用,如下所示:

=GETFROMHTML(E2; "<h3 class=""product-name""")
Run Code Online (Sandbox Code Playgroud)

或者

=GETFROMHTML(E2; "<span class=""price""")
Run Code Online (Sandbox Code Playgroud)

使用 aSub可能看起来像这样:

sub getProductNameAndPrice()
   on error resume next

   oDoc = ThisComponent
   oSheet = oDoc.CurrentController.ActiveSheet

   for r = 0 to 9 'row 1 to 10 (0 based)

     sURL = oSheet.getCellByPosition(4, r).String 'get string value from column 4 (E)

     oSimpleFileAccess = createUNOService ("com.sun.star.ucb.SimpleFileAccess")
     oInpDataStream = createUNOService ("com.sun.star.io.TextInputStream")
     oInpDataStream.setInputStream(oSimpleFileAccess.openFileRead(sUrl))
     if not isNull(oInpDataStream.InputStream) then 
       dim delimiters() as long
       sContent = oInpDataStream.readString(delimiters(), false)

       sStartTag = "<h3 class=""product-name"""

       lStartPos = instr(1, sContent, sStartTag)
       if lStartPos <> 0 then
         lEndPos = instr(lStartPos, sContent, "</")
         lStartPos = lStartPos + 1 + len(sStartTag)
         sText = trim(replace(replace(mid(sContent, lStartPos, lEndPos-lStartPos), chr(10), ""), chr(13), ""))

         oSheet.getCellByPosition(5, r).String = sText
       end if 

       sStartTag = "<span class=""price"""

       lStartPos = instr(1, sContent, sStartTag)
       if lStartPos <> 0 then
         lEndPos = instr(lStartPos, sContent, "</")
         lStartPos = lStartPos + 1 + len(sStartTag)
         sText = trim(replace(replace(mid(sContent, lStartPos, lEndPos-lStartPos), chr(10), ""), chr(13), ""))

         oSheet.getCellByPosition(6, r).String = sText
       end if   

     end if

   next

   on error goto 0
end sub
Run Code Online (Sandbox Code Playgroud)

E此代码获取列第 1 行到第 10 行的 URL ,并在列中写入产品名称F,在该行的列中写入价格G