使用Floki和HttPotion的Elixir脚本无法解析url
我正试图用维基百科的文章和文本来编写一个脚本。我的失败代码如下所示:使用Floki和HttPotion的Elixir脚本无法解析url,url,enums,web-scraping,html-parsing,elixir,Url,Enums,Web Scraping,Html Parsing,Elixir,我正试图用维基百科的文章和文本来编写一个脚本。我的失败代码如下所示: defmodule Scraper do def start do base = "https://en.wikipedia.org" response = HTTPotion.get base <> "/wiki/Main_Page" html = response.body main_bg = Floki.find(html, ".MainPageBG") main
defmodule Scraper do
def start do
base = "https://en.wikipedia.org"
response = HTTPotion.get base <> "/wiki/Main_Page"
html = response.body
main_bg = Floki.find(html, ".MainPageBG")
main_bg
|> Floki.find("table tr li a")
|> Floki.attribute("href")
|> Enum.map(fn(addr) -> HTTPotion.get(base <> addr) end)
end
end
当我将结果通过管道传输到Floki.attribute(“href”)
时,我会得到一个很好的url路径名列表,如:
["/wiki/Japanese_aircraft_carrier_Hiry%C5%ABwow",
"/wiki/Boys_Don%27t_Cry_(film)wow", "/wiki/Elias_Abraham_Rosenbergwow",
"/wiki/Japanese_aircraft_carrier_Hiry%C5%ABwow",
"/wiki/Boys_Don%27t_Cry_(film)wow", "/wiki/Elias_Abraham_Rosenbergwow",
"/wiki/Wikipedia:Today%27s_featured_article/November_2015wow",
"https://lists.wikimedia.org/mailman/listinfo/daily-article-lwow",
"/wiki/Wikipedia:Featured_articleswow", "/wiki/Schloss_Krobnitzwow",
"/wiki/Prussiawow", "/wiki/Albrecht_von_Roonwow", "/wiki/Harry_Winerwow",
"/wiki/Rob_Thomas_(writer)wow", "/wiki/Of_Vice_and_Menwow",
"/wiki/Veronica_Marswow", "/wiki/Meithalunwow", "/wiki/Palestinian_peoplewow",
"/wiki/Marj_Sanurwow", "/wiki/Soma_Norodomwow",...]
但是,当行|>Enum.map(fn(addr)->HTTPotion.get(base addr)end)
运行时,我得到以下错误:
** (HTTPotion.HTTPError) {:url_parsing_failed, {:error, :invalid_uri}}
(httpotion) lib/httpotion.ex:209: HTTPotion.handle_response/1
(elixir) lib/enum.ex:977: anonymous fn/3 in Enum.map/2
(elixir) lib/enum.ex:1261: Enum."-reduce/3-lists^foldl/2-0-"/3
(elixir) lib/enum.ex:977: Enum.map/2
我看到:url\u解析\u失败了
,但我不明白为什么。当我使用列表中的各个url路径尝试Enum.map(fn(addr)->HTTPotion.get(base addr)
时,它们都可以工作
- 我的语法错了吗
- 我是否遗漏了一些关于管道或枚举如何工作的信息
- 我走对了吗
defmodule Scraper do
def transform_url(url_or_path = "/" <> _, base), do: base <> url_or_path
def transform_url(url, _base), do: url
def start do
base = "https://en.wikipedia.org"
response = HTTPotion.get base <> "/wiki/Main_Page"
html = response.body
main_bg = Floki.find(html, ".MainPageBG")
main_bg
|> Floki.find("table tr li a")
|> Floki.attribute("href")
|> Enum.map(fn(url) -> OldRazor.transform_url(url, base) end)
|> Enum.map(fn(url) -> HTTPotion.get(url) end)
end
end
defmodule-Scraper-do
def transform_url(url_或_path=“/”,基本),do:base url_或_path
def transform_url(url,_base),do:url
def启动do
基数=”https://en.wikipedia.org"
response=HTTPotion.get base”/wiki/Main\u页面
html=response.body
main_bg=Floki.find(html,“.MainPageBG”)
主接线盒
|>Floki.find(“表tr li a”)
|>属性(“href”)
|>Enum.map(fn(url)->OldRazor.transform\u url(url,base)end)
|>映射(fn(url)->HTTPotion.get(url)end)
结束
结束
如果您再次仔细查看url列表,您会注意到其中有一个绝对url:“”。这不适用于HTTPotion.get(base addr)
,因为它最终会请求类似“”的url
解决此问题的一种方法是编写另一个函数transform\u url
,该函数检查值是否以/
开头,然后才将基本url前置到该值:
def transform_url(url_or_path = "/" <> _, base), do: base <> url_or_path
def transform_url(url, _base), do: url
实际上,我运行了你的代码,但在
HTTPotion.get!
部分前面的匿名函数中加入了一个IO.inspect(url)
。所以最后打印的url是一个坏的url。经过一些调整,效果很好!谢谢。我没有真正理解(url\u或\u path=“/”,base)
的功能。太棒了!url\u或\u path=“/”_
匹配以/
开头的二进制文件,然后将整个二进制文件绑定到url\u或_path
,如果匹配的话。因此,基本上整个方法的作用类似于:如果第一个参数以“/”开头,将该参数绑定到url\u或\u path
,在base
前加前缀并返回该参数。否则只需返回第一个参数。哦,太棒了。再次感谢。
def transform_url(url_or_path = "/" <> _, base), do: base <> url_or_path
def transform_url(url, _base), do: url
...
|> Enum.map(fn(url) -> HTTPoison.get!(transform_url((url)) end)