def METHOD_NAME(self, item):
    # skip header rows
    if item.get("class") not in ["rounded odd", "rounded even"]:
        self.skip("header row")
    name_dirty = (
        CSS("span.info strong").match(item)[0].text_content().strip().split(", ")
    )
    if len(name_dirty) > 1:
        name = f"{name_dirty[1]} {name_dirty[0]}"
    elif len(name_dirty) == 1:
        name = name_dirty[0]
    else:
        self.skip("empty name")
    if name == "Vacant":
        self.skip("vacant")
    party = CSS("span.info small").match(item)[0].text_content().strip()
    party = self.party_re.search(party).groups()[0]
    if party == "D":
        party = "Democratic"
    elif party == "R":
        party = "Republican"
    elif party == "I":
        party = "Independent"
    district = CSS("span small").match(item)[1].text_content().strip()
    district = re.search(r"District\s(.+)", district).groups()[0]
    p = ScrapePerson(
        name=name,
        state="wi",
        chamber=self.chamber,
        district=district,
        party=party,
    )
    # which one should be 'homepage'?
    # https://legis.wisconsin.gov/senate/16/agard, website currently adding to extras
    # https://docs.legis.wisconsin.gov/2023/legislators/senate/2251, detail_link adding as source and scraping
    website = CSS("span.info strong a").match_one(item).get("href")
    p.extras["website"] = website
    detail_link = (
        XPath(".//a[contains(text(), 'Details')]").match_one(item).get("href")
    )
    p.add_source(self.source.url, note="members list page")
    p.add_source(detail_link, note="member detail page")
    try:
        title = (
            CSS("span.info span span strong").match_one(item).text_content().strip()
        )
        p.extras["title"] = title
    except SelectorError:
        pass
    email = CSS("span.info.email a").match_one(item).text_content().strip()
    p.email = email
    no_photo = len(item.xpath(".//span[@class='picture-placeholder']"))
    if no_photo:
        img = ""
    else:
        img = CSS("img").match_one(item).get("src")
    p.image = img
    phones = (
        CSS("span.info.telephone")
        .match_one(item)
        .text_content()
        .strip()
        .split("\n")
    )
    phones = re.search(
        r"(\(\d{3}\)\s\d{3}-\d{4})(\(?\d{0,3}\)?\s?\d{0,3}-?\d{0,4})", phones[1]
    ).groups()
    p.capitol_office.voice = phones[0]
    if len(phones) > 1:
        p.extras["extra phone"] = phones[1]
    try:
        district_phone = (
            CSS("span.info.district_phone")
            .match_one(item)
            .text_content()
            .split("\n")[2]
            .strip()
        )
        p.district_office.voice = district_phone
    except SelectorError:
        pass
    return LegDetail(p, source=detail_link)