Skip to contents

Reduces a Screaming Frog Link Path to the **component the link sits in**, stable across every page that component appears on. This is the identity the boilerplate detector conditions on: see pagerank()'s container_col.

Two steps:

  1. **Strip numeric predicates, keep class predicates.** Screaming Frog's Link Path is a hybrid, using [@class='...'] where classes exist and positional [n] elsewhere. Positions are unstable — the same recycled call-to-action lands at p[5] on a post with four preceding paragraphs and p[3] on a shorter one — while a class is exactly the stable component identifier we want.

  2. **Drop the trailing <a> step**, whatever predicate it carries. The anchor's own class describes the link, not the component containing it.

Note this cuts the **opposite** way from sf_region_from_path(), which strips class predicates so that a div[@class='site-footer'] is not mistaken for a <footer>. The two answer different questions — *which region is this* versus *is this the same component* — and the inconsistency is deliberate.

Usage

sf_container_from_path(x)

Arguments

x

A vector (typically character) of Screaming Frog link paths, e.g. "//body/main/article/p[5]/a[1]".

Value

A character vector the same length as x holding the container path. Blank strings and NA yield NA, leaving those rows unscored by the detector.

See also

[pagerank()], whose `container_col` consumes the result.

Other Screaming Frog toolkit: sf_contract(), sf_graph_eligible(), sf_normalize_position(), sf_parse_follow(), sf_read_input(), sf_region_from_path(), sf_rel_nofollow()

Examples

sf_container_from_path(c(
  "//body/main/article/p[5]/a[1]", # positions stripped
  "//body/main/article/p[3]/a[1]", # ... so these two agree
  "//body/div[@class='cta']/a", # class kept as the component identity
  "//body/div[@class='cta']/a[@class='btn']" # anchor's own class dropped
))
#> [1] "//body/main/article/p"    "//body/main/article/p"   
#> [3] "//body/div[@class='cta']" "//body/div[@class='cta']"