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

时间:2018-05-19 13:53:28

标签: web libreoffice-calc

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

之前我使用的是带有IMPORTXML功能的Google表格,但由于它非常不可靠,我想改用Calc。

我的功能看起来像这样:

  

= IMPORTXML(E2;“// h3 [@ class ='product-name']”)

     

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

正如您已经猜到的,网址位于E2(f.i。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中此函数的等价物是什么?产品名称和价格的相应命令如何?

非常感谢提前!

1 个答案:

答案 0 :(得分:3)

问题在于虽然IMPORTXML声称能够解析标签汤HTML,但并非所有情况都是如此,FILTERXML每个定义都需要一个有效的XML流。标签汤HTML不是有效的XML流。说实话,HTML主要与有效的XML流相反。

所以唯一的方法是使用第三方标记汤解析器或将HTML标记汤作为字符串并使用字符串操作来查找字符串所需的部分。

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

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

在Calc细胞中使用如下:

=GETFROMHTML(E2; "<h3 class=""product-name""")

=GETFROMHTML(E2; "<span class=""price""")

使用Sub可能如下所示:

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

此代码从第{1}行第1行到第10行获取网址,并在第E栏中写入产品名称,在该行的第F栏中写入价格。