Packages
floki
0.7.2
0.38.4
0.38.3
0.38.2
0.38.1
0.38.0
0.37.1
0.37.0
0.36.3
0.36.2
0.36.1
0.36.0
0.35.4
0.35.3
0.35.2
0.35.1
0.35.0
0.34.3
0.34.2
0.34.1
0.34.0
0.33.1
0.33.0
0.32.1
0.32.0
0.31.0
0.30.1
0.30.0
0.29.0
0.28.0
0.27.0
0.26.0
0.25.0
0.24.0
0.23.1
0.23.0
0.22.0
0.21.0
0.20.4
0.20.3
0.20.2
0.20.1
0.20.0
0.19.3
0.19.2
0.19.1
0.19.0
0.18.1
0.18.0
0.17.2
0.17.1
0.17.0
0.16.0
0.15.0
0.14.0
0.13.2
0.13.1
0.13.0
0.12.1
0.12.0
0.11.0
0.10.1
0.10.0
0.9.0
0.8.1
0.8.0
0.7.2
0.7.1
0.7.0
0.6.1
0.6.0
0.5.0
0.4.1
0.4.0
0.3.3
0.3.2
0.3.1
0.3.0
0.2.1
0.2.0
0.1.1
0.1.0
0.0.5
0.0.4
0.0.3
0.0.2
0.0.1
Floki is a simple HTML parser that enables search for nodes using CSS selectors.
Current section
86 Versions
Jump to
Current section
86 Versions
Compare versions
10
files changed
+128
additions
-157
deletions
| @@ -7,14 +7,11 @@ | |
| 7 7 | |
| 8 8 | Floki is a simple HTML parser that enables search for nodes using CSS selectors. |
| 9 9 | |
| 10 | - You can perform searches using classes, attributes, tag names and IDs. |
| 11 | - You can also combine selectors and use groups, like: `"a.foo[data-action='bar'], .baz.zaz"`. |
| 12 | - |
| 13 10 | [Check the documentation](http://hexdocs.pm/floki). |
| 14 11 | |
| 15 12 | ## Usage |
| 16 13 | |
| 17 | - Assuming that you have the following HTML: |
| 14 | + Take this HTML as an example: |
| 18 15 | |
| 19 16 | ```html |
| 20 17 | <!doctype html> |
| @@ -97,7 +94,7 @@ It is simple as that! | |
| 97 94 | |
| 98 95 | ## Installation |
| 99 96 | |
| 100 | - You can install Floki by adding a dependency to your mix file (mix.exs): |
| 97 | + Add Floki in your `mix.exs`, as a dependency: |
| 101 98 | |
| 102 99 | ```elixir |
| 103 100 | defp deps do |
| @@ -1,7 +1,7 @@ | |
| 1 1 | {<<"app">>,<<"floki">>}. |
| 2 2 | {<<"build_tools">>,[<<"mix">>]}. |
| 3 3 | {<<"description">>, |
| 4 | - <<"A HTML parser and searcher.\n\nYou can search inside HTML documents using CSS selectors.">>}. |
| 4 | + <<"Floki is a simple HTML parser that enables search for nodes using CSS selectors.">>}. |
| 5 5 | {<<"elixir">>,<<">= 1.0.0">>}. |
| 6 6 | {<<"files">>, |
| 7 7 | [<<"lib/floki.ex">>,<<"lib/floki/attribute_selector.ex">>, |
| @@ -22,4 +22,4 @@ | |
| 22 22 | [{<<"app">>,<<"mochiweb">>}, |
| 23 23 | {<<"optional">>,false}, |
| 24 24 | {<<"requirement">>,<<"~> 2.12.2">>}]}]}. |
| 25 | - {<<"version">>,<<"0.7.1">>}. |
| 25 | + {<<"version">>,<<"0.7.2">>}. |
| @@ -1,13 +1,10 @@ | |
| 1 1 | defmodule Floki do |
| 2 2 | alias Floki.Finder |
| 3 3 | alias Floki.Parser |
| 4 | + alias Floki.FilterOut |
| 4 5 | |
| 5 6 | @moduledoc """ |
| 6 | - A HTML parser and seeker. |
| 7 | - |
| 8 | - This is a simple HTML parser that enables searching using CSS like selectors. |
| 9 | - |
| 10 | - You can search elements by class, tag name and id. |
| 7 | + Floki is a simple HTML parser that enables search for nodes using CSS selectors. |
| 11 8 | |
| 12 9 | ## Example |
| 13 10 | |
| @@ -26,14 +23,14 @@ defmodule Floki do | |
| 26 23 | </html> |
| 27 24 | ``` |
| 28 25 | |
| 29 | - You can perform the following queries: |
| 26 | + Examples of queries that you can perform: |
| 30 27 | |
| 31 | - * Floki.find(html, "#content") : returns the section with all children; |
| 32 | - * Floki.find(html, ".headline") : returns a list with the `p` element; |
| 33 | - * Floki.find(html, "a") : returns a list with the `a` element; |
| 34 | - * Floki.find(html, "[data-model=user]") : returns a list with elements that match that data attribute; |
| 35 | - * Floki.find(html, "#content a") # returns all links inside content section; |
| 36 | - * Floki.find(html, ".headline, a") # returns the .headline elements and links. |
| 28 | + * Floki.find(html, "#content") |
| 29 | + * Floki.find(html, ".headline") |
| 30 | + * Floki.find(html, "a") |
| 31 | + * Floki.find(html, "[data-model=user]") |
| 32 | + * Floki.find(html, "#content a") |
| 33 | + * Floki.find(html, ".headline, a") |
| 37 34 | |
| 38 35 | Each HTML node is represented by a tuple like: |
| 39 36 | |
| @@ -91,6 +88,8 @@ defmodule Floki do | |
| 91 88 | |
| 92 89 | """ |
| 93 90 | |
| 91 | + @spec raw_html(html_tree) :: binary |
| 92 | + |
| 94 93 | def raw_html(html_tree), do: raw_html(html_tree, "") |
| 95 94 | defp raw_html([], html), do: html |
| 96 95 | defp raw_html(tuple, html) when is_tuple(tuple), do: raw_html([tuple], html) |
| @@ -138,7 +137,7 @@ defmodule Floki do | |
| 138 137 | @spec find(binary | html_tree, binary) :: html_tree |
| 139 138 | |
| 140 139 | def find(html, selector) when is_binary(html) do |
| 141 | - parse(html) |> Finder.find(selector) |
| 140 | + html |> parse |> Finder.find(selector) |
| 142 141 | end |
| 143 142 | def find(html_tree, selector) do |
| 144 143 | Finder.find(html_tree, selector) |
| @@ -170,14 +169,15 @@ defmodule Floki do | |
| 170 169 | |
| 171 170 | def text(html, opts \\ [deep: true, js: false]) do |
| 172 171 | html_tree = |
| 173 | - case is_binary(html) do |
| 174 | - true -> parse(html) |
| 175 | - false -> html |
| 172 | + if is_binary(html) do |
| 173 | + parse(html) |
| 174 | + else |
| 175 | + html |
| 176 176 | end |
| 177 177 | |
| 178 178 | cleaned_html_tree = |
| 179 179 | case opts[:js] do |
| 180 | - true -> html_tree |
| 180 | + true -> html_tree |
| 181 181 | _ -> filter_out(html_tree, "script") |
| 182 182 | end |
| 183 183 | |
| @@ -262,6 +262,9 @@ defmodule Floki do | |
| 262 262 | iex> Floki.filter_out([{"body", [], [{"script", [], []},{"div", [], []}]}], "script") |
| 263 263 | [{"body", [], [{"div", [], []}]}] |
| 264 264 | |
| 265 | + iex> Floki.filter_out("<div><!-- comment --> text</div>", :comment) |
| 266 | + {"div", [], [" text"]} |
| 267 | + |
| 265 268 | """ |
| 266 269 | |
| 267 270 | @spec filter_out(binary | html_tree, binary) :: list |
| @@ -269,11 +272,9 @@ defmodule Floki do | |
| 269 272 | def filter_out(html_tree, selector) when is_binary(html_tree) do |
| 270 273 | html_tree |
| 271 274 | |> parse |
| 272 | - |> Floki.FilterOut.filter_out(selector) |
| 275 | + |> FilterOut.filter_out(selector) |
| 273 276 | end |
| 274 277 | def filter_out(elements, selector) do |
| 275 | - Floki.FilterOut.filter_out(elements, selector) |
| 278 | + FilterOut.filter_out(elements, selector) |
| 276 279 | end |
| 277 | - |
| 278 | - |
| 279 280 | end |
| @@ -22,7 +22,7 @@ defmodule Floki.AttributeSelector do | |
| 22 22 | |
| 23 23 | whitespace_values = String.split(value, " ") |
| 24 24 | |
| 25 | - Enum.any? whitespace_values, fn(v) -> v == s.value end |
| 25 | + Enum.any?(whitespace_values, fn(v) -> v == s.value end) |
| 26 26 | end |
| 27 27 | def match?(attributes, s = %AttributeSelector{match_type: :dash_match}) do |
| 28 28 | value = get_value(s.attribute, attributes) |
| @@ -30,24 +30,24 @@ defmodule Floki.AttributeSelector do | |
| 30 30 | value == s.value || String.starts_with?(value, "#{s.value}-") |
| 31 31 | end |
| 32 32 | def match?(attributes, s = %AttributeSelector{match_type: :prefix_match}) do |
| 33 | - get_value(s.attribute, attributes) |> String.starts_with?(s.value) |
| 33 | + s.attribute |> get_value(attributes) |> String.starts_with?(s.value) |
| 34 34 | end |
| 35 35 | def match?(attributes, s = %AttributeSelector{match_type: :sufix_match}) do |
| 36 | - get_value(s.attribute, attributes) |> String.ends_with?(s.value) |
| 36 | + s.attribute |> get_value(attributes) |> String.ends_with?(s.value) |
| 37 37 | end |
| 38 38 | def match?(attributes, s = %AttributeSelector{match_type: :substring_match}) do |
| 39 | - get_value(s.attribute, attributes) |> String.contains?(s.value) |
| 39 | + s.attribute |> get_value(attributes) |> String.contains?(s.value) |
| 40 40 | end |
| 41 41 | |
| 42 42 | defp get_value(attr_name, attributes) do |
| 43 | - {_attr_name, value} = Enum.find attributes, {attr_name, ""}, fn({k, _v}) -> |
| 43 | + {_attr_name, value} = Enum.find(attributes, {attr_name, ""}, fn({k, _v}) -> |
| 44 44 | k == attr_name |
| 45 | - end |
| 45 | + end) |
| 46 46 | |
| 47 47 | value |
| 48 48 | end |
| 49 49 | |
| 50 50 | defp attribute_present?(name, attributes) do |
| 51 | - Enum.any? attributes, fn({k, _v}) -> k == name end |
| 51 | + Enum.any?(attributes, fn({k, _v}) -> k == name end) |
| 52 52 | end |
| 53 53 | end |
| @@ -29,6 +29,7 @@ defmodule Floki.DeepText do | |
| 29 29 | end |
| 30 30 | end |
| 31 31 | defp get_text({:comment, _}, acc), do: acc |
| 32 | + defp get_text({"br", _, _}, acc), do: acc <> "\n" |
| 32 33 | defp get_text({_, _, nodes}, acc) do |
| 33 34 | get_text(nodes, acc) |
| 34 35 | end |
Loading more files…