pdf文件链接的网络抓取不起作用



我尝试从网页抓取pdf文件(https://kodis-files.s3 .....)的链接,但没有成功。

我使用f#,但我希望那些用其他。net语言编码的人会发现代码并不难读。

我使用了这两种方法(代码被简化了,结果被打印出来,而不是用在其他地方):

//*******************************************
let url0 = "https://www.kodis.cz/lines/region?tab=232-293"
let document0 = HtmlDocument.Load(url0)
document0.CssSelect("div#__next") 
|> List.iter (fun item ->
let querySelector (tag: string) = (item.Descendants tag)                           
(querySelector "a")
|> Seq.iter (fun item ->      
let url = item.AttributeValue "href"
printfn "%s" url
)           
) 
//*******************************************
let url = "https://www.kodis.cz/lines/region?tab=232-293" 
let document = HtmlDocument.Load(url)
let links =
document.Descendants "a"
|> Seq.choose (fun x ->
x.TryGetAttribute("href")
|> Option.map (fun a -> x.InnerText(), a.Value())
) |> Seq.toList   
printfn "%A" links 

两种变体都会抓取网站上的所有链接pdf文件链接除外.

到相关网页的链接在代码中。我已经提取了部分html代码,这是有关我的问题。

<div id="__next" data-reactroot="">
<!-- many "a hrefs" with links to various stuff -->
<main class="mt-16">
<div class="container">         
<div class="mb-12">
<ul class="mb-8 grid grid-cols-1 gap-4 md:grid-cols-2 xl:grid-cols-2">
<li class="Card_wrapper__ZQ5Fp">                        
<div class="Card_actions__HhB_f">
<a href="https://kodis-files.s3.eu-central-1.amazonaws.com/232_2022_12_11_2023_12_09_d02eef94bc.pdf" target="_blank" class="Button_main__pEB6O Button_secondary__R6QEg Button_md__1RLR1" data-testid="button-elementAnchor" title="Pravidelný jízdní řád">                              
</a>
</div>
</li>
<li class="Card_wrapper__ZQ5Fp">                        
<!-- another "a href" with a link to a pdf file -->                         
</li>
<li class="Card_wrapper__ZQ5Fp">
<!-- another "a href" with a link to a pdf file -->
</li>                   
</ul>               
</div>
</div>
</main>
</div>

我做错了什么?有没有可能用一些"防刮"剂?SW受雇于网站的创建者?

编辑:正如Jim Foye所建议的,pdf链接似乎是由JavaScript创建的,因此不可能在FSharp.DataHtmlAgilityPack.Net.WebClient.Net.Http.HttpClientwget的帮助下被抓取。如果这个问题的唯一解决方案是获得html代码相同的方式作为浏览器保存代码,请参阅相关问题。如果不能,请在这里提出解决方法。

我在链接的问题中看到你找到了一种方法来做到这一点。如果你能找到页面是如何由JavaScript生成的(正如你所做的),那么直接获取数据是最优的。

然而,如果这不起作用,也有一个很好的f#库顶盖,它可以让你自动运行浏览器——这样你就可以在浏览器中加载页面,然后提取链接:

#r "nuget:canopy"
open canopy
open canopy.classic
// Download chromedriver.exe from
// https://chromedriver.chromium.org/downloads
canopy.configuration.chromeDir <- "c:/temp/driver"
start chrome
url "https://www.kodis.cz/lines/region?tab=232-293"

你可以在f# Interactive中以交互方式运行上面的代码,等待页面加载&执行如下命令:

for el in elements "a" do
let href = el.GetAttribute("href")
if href.EndsWith("pdf") then
printfn "%A" href

2023年4月7日,编辑 ***********************************

如果不在FS Interactive中运行代码,则可能需要在for循环之前添加如下代码:

let linksShown () = (elements ".Card_wrapper__ZQ5Fp").Length >= 11 
//a condition for waitFor  

compareTimeout <- 10.0 //probably needed for slow connections
waitFor linksShown  //waiting until the needed number of elements are downloaded

还可以查看其他Canopy的内容,如waitforElement

编辑 **********************************************

如果页面只是渐进式加载数据,这可能也很有用。例如,你可以模拟点击"Další"按钮加载更多数据:

click (elementWithText "a" "Další")

最新更新