prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  NY: Native American Relations committee is not being scraped correctly
  http://www.nysenate.gov/committee/state-native-american-relations
  http://openstates.org/admin/object_json/committees/NYC000116/
  
  
  --- END ISSUE ---
  
  Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
  --- BEGIN FILES ---
  Path: `openstates/ny/committees.py`
  Content:
  ```
  1 import re
  2 
  3 from billy.scrape import NoDataForPeriod
  4 from billy.scrape.committees import CommitteeScraper, Committee
  5 
  6 import lxml.html
  7 
  8 
  9 def parse_name(name):
  10     """
  11     Split a committee membership string into name and role.
  12 
  13     >>> parse_name('Felix Ortiz')
  14     ('Felix Ortiz', 'member')
  15     >>> parse_name('Felix Ortiz (Chair)')
  16     ('Felix Ortiz', 'chair')
  17     >>> parse_name('Hon. Felix Ortiz, Co-Chair')
  18     ('Felix Ortiz', 'co-chair')
  19     >>> parse_name('Owen H.\\r\\nJohnson (Vice Chairperson)')
  20     ('Owen H. Johnson', 'vice chairperson')
  21     """
  22     name = re.sub(r'^(Hon\.|Assemblyman|Assemblywoman)\s+', '', name)
  23     name = re.sub(r'\s+', ' ', name)
  24 
  25     roles = ["Chairwoman", "Chairperson", "Chair", "Secretary", "Treasurer",
  26              "Parliamentarian", "Chaplain"]
  27     match = re.match(
  28         r'([^(]+),? \(?((Co|Vice)?-?\s*(%s))\)?' % '|'.join(roles),
  29         name)
  30 
  31     if match:
  32         name = match.group(1).strip(' ,')
  33         role = match.group(2).lower()
  34         return (name, role)
  35     return (name, 'member')
  36 
  37 
  38 class NYCommitteeScraper(CommitteeScraper):
  39     state = "ny"
  40     latest_only = True
  41 
  42     def scrape(self, chamber, term):
  43         getattr(self, 'scrape_' + chamber)()
  44 
  45     def scrape_lower(self, only_names=None):
  46         committees = []
  47         url = "http://assembly.state.ny.us/comm/"
  48         page = self.urlopen(url)
  49         page = lxml.html.fromstring(page)
  50         page.make_links_absolute(url)
  51 
  52         for link in page.xpath("//a[contains(@href, 'sec=mem')]"):
  53             name = link.xpath("string(../strong)").strip()
  54             if 'Caucus' in name:
  55                 continue
  56 
  57             url = link.attrib['href']
  58 
  59             committees.append(name)
  60 
  61             self.scrape_lower_committee(name, url)
  62         return committees
  63 
  64     def scrape_lower_committee(self, name, url):
  65         page = self.urlopen(url)
  66         page = lxml.html.fromstring(page)
  67 
  68         comm = Committee('lower', name)
  69         comm.add_source(url)
  70 
  71         for link in page.xpath("//div[@class='commlinks']//a[contains(@href, 'mem')]"):
  72             member = link.text.strip()
  73             member = re.sub(r'\s+', ' ', member)
  74 
  75             name, role = parse_name(member)
  76             comm.add_member(name, role)
  77 
  78         self.save_committee(comm)
  79 
  80     def scrape_upper(self):
  81         committees = []
  82         url = "http://www.nysenate.gov/committees"
  83         page = self.urlopen(url)
  84         page = lxml.html.fromstring(page)
  85         page.make_links_absolute(url)
  86 
  87         for link in page.xpath("//a[contains(@href, '/committee/')]"):
  88             name = link.text.strip()
  89 
  90             if name == 'New York State Conference of Black Senators':
  91                 # stop scraping once we reach the caucuses
  92                 break
  93 
  94             committees.append(name)
  95             self.scrape_upper_committee(name, link.attrib['href'])
  96         return committees
  97 
  98     def scrape_upper_committee(self, name, url):
  99         page = self.urlopen(url)
  100         page = lxml.html.fromstring(page)
  101 
  102         comm = Committee('upper', name)
  103         comm.add_source(url)
  104 
  105         member_div = page.xpath("//div[@class = 'committee-members']")[0]
  106 
  107         seen = set()
  108         for link in member_div.xpath(".//a"):
  109             if not link.text:
  110                 continue
  111 
  112             member = link.text.strip()
  113 
  114             next_elem = link.getnext()
  115             if (next_elem is not None and
  116                 next_elem.tag == 'a' and
  117                 next_elem.attrib['href'] == link.attrib['href']):
  118                 # Sometimes NY is cool and splits names across a
  119                 # couple links
  120                 member = "%s %s" % (member, next_elem.text.strip())
  121 
  122             member = re.sub(r'\s+', ' ', member)
  123 
  124             if member in seen or not member:
  125                 continue
  126             seen.add(member)
  127 
  128             name, role = parse_name(member)
  129             comm.add_member(name, role)
  130 
  131         self.save_committee(comm)
  132
  ```
  --- END FILES ---
  
  Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.
  
  Here is an example:
  
  ```diff
  diff --git a/examples/server_async.py b/examples/server_async.py
  --- a/examples/server_async.py
  +++ b/examples/server_async.py
  @@ -313,4 +313,4 @@
   
   
   if __name__ == "__main__":
  -    asyncio.run(run_async_server("."), debug=True)
  +    asyncio.run(run_async_server(), debug=True)
  diff --git a/examples/server_sync.py b/examples/server_sync.py
  --- a/examples/server_sync.py
  +++ b/examples/server_sync.py
  @@ -313,5 +313,5 @@
   
   
   if __name__ == "__main__":
  -    server = run_sync_server(".")
  +    server = run_sync_server()
       server.shutdown()
  
  ```
  
golden_diff: diff --git a/openstates/ny/committees.py b/openstates/ny/committees.py
  --- a/openstates/ny/committees.py
  +++ b/openstates/ny/committees.py
  @@ -84,15 +84,17 @@
           page = lxml.html.fromstring(page)
           page.make_links_absolute(url)
   
  -        for link in page.xpath("//a[contains(@href, '/committee/')]"):
  -            name = link.text.strip()
  +        for h2 in page.xpath("//h2"):
  +            committee_types = ['Standing Committees','Temporary Committees']
  +            if h2.text not in committee_types:
  +                continue
  +            
  +            for link in h2.getparent().xpath(".//a[contains(@href, '/committee/')]"):
  +                name = link.text.strip()
   
  -            if name == 'New York State Conference of Black Senators':
  -                # stop scraping once we reach the caucuses
  -                break
  +                committees.append(name)
  +                self.scrape_upper_committee(name, link.attrib['href'])
   
  -            committees.append(name)
  -            self.scrape_upper_committee(name, link.attrib['href'])
           return committees
   
       def scrape_upper_committee(self, name, url):
  
verification_info: {"golden_diff": "diff --git a/openstates/ny/committees.py b/openstates/ny/committees.py\n--- a/openstates/ny/committees.py\n+++ b/openstates/ny/committees.py\n@@ -84,15 +84,17 @@\n         page = lxml.html.fromstring(page)\n         page.make_links_absolute(url)\n \n-        for link in page.xpath(\"//a[contains(@href, '/committee/')]\"):\n-            name = link.text.strip()\n+        for h2 in page.xpath(\"//h2\"):\n+            committee_types = ['Standing Committees','Temporary Committees']\n+            if h2.text not in committee_types:\n+                continue\n+            \n+            for link in h2.getparent().xpath(\".//a[contains(@href, '/committee/')]\"):\n+                name = link.text.strip()\n \n-            if name == 'New York State Conference of Black Senators':\n-                # stop scraping once we reach the caucuses\n-                break\n+                committees.append(name)\n+                self.scrape_upper_committee(name, link.attrib['href'])\n \n-            committees.append(name)\n-            self.scrape_upper_committee(name, link.attrib['href'])\n         return committees\n \n     def scrape_upper_committee(self, name, url):\n", "issue": "NY: Native American Relations committee is not being scraped correctly\nhttp://www.nysenate.gov/committee/state-native-american-relations\nhttp://openstates.org/admin/object_json/committees/NYC000116/\n\n", "before_files": [{"content": "import re\n\nfrom billy.scrape import NoDataForPeriod\nfrom billy.scrape.committees import CommitteeScraper, Committee\n\nimport lxml.html\n\n\ndef parse_name(name):\n    \"\"\"\n    Split a committee membership string into name and role.\n\n    >>> parse_name('Felix Ortiz')\n    ('Felix Ortiz', 'member')\n    >>> parse_name('Felix Ortiz (Chair)')\n    ('Felix Ortiz', 'chair')\n    >>> parse_name('Hon. Felix Ortiz, Co-Chair')\n    ('Felix Ortiz', 'co-chair')\n    >>> parse_name('Owen H.\\\\r\\\\nJohnson (Vice Chairperson)')\n    ('Owen H. Johnson', 'vice chairperson')\n    \"\"\"\n    name = re.sub(r'^(Hon\\.|Assemblyman|Assemblywoman)\\s+', '', name)\n    name = re.sub(r'\\s+', ' ', name)\n\n    roles = [\"Chairwoman\", \"Chairperson\", \"Chair\", \"Secretary\", \"Treasurer\",\n             \"Parliamentarian\", \"Chaplain\"]\n    match = re.match(\n        r'([^(]+),? \\(?((Co|Vice)?-?\\s*(%s))\\)?' % '|'.join(roles),\n        name)\n\n    if match:\n        name = match.group(1).strip(' ,')\n        role = match.group(2).lower()\n        return (name, role)\n    return (name, 'member')\n\n\nclass NYCommitteeScraper(CommitteeScraper):\n    state = \"ny\"\n    latest_only = True\n\n    def scrape(self, chamber, term):\n        getattr(self, 'scrape_' + chamber)()\n\n    def scrape_lower(self, only_names=None):\n        committees = []\n        url = \"http://assembly.state.ny.us/comm/\"\n        page = self.urlopen(url)\n        page = lxml.html.fromstring(page)\n        page.make_links_absolute(url)\n\n        for link in page.xpath(\"//a[contains(@href, 'sec=mem')]\"):\n            name = link.xpath(\"string(../strong)\").strip()\n            if 'Caucus' in name:\n                continue\n\n            url = link.attrib['href']\n\n            committees.append(name)\n\n            self.scrape_lower_committee(name, url)\n        return committees\n\n    def scrape_lower_committee(self, name, url):\n        page = self.urlopen(url)\n        page = lxml.html.fromstring(page)\n\n        comm = Committee('lower', name)\n        comm.add_source(url)\n\n        for link in page.xpath(\"//div[@class='commlinks']//a[contains(@href, 'mem')]\"):\n            member = link.text.strip()\n            member = re.sub(r'\\s+', ' ', member)\n\n            name, role = parse_name(member)\n            comm.add_member(name, role)\n\n        self.save_committee(comm)\n\n    def scrape_upper(self):\n        committees = []\n        url = \"http://www.nysenate.gov/committees\"\n        page = self.urlopen(url)\n        page = lxml.html.fromstring(page)\n        page.make_links_absolute(url)\n\n        for link in page.xpath(\"//a[contains(@href, '/committee/')]\"):\n            name = link.text.strip()\n\n            if name == 'New York State Conference of Black Senators':\n                # stop scraping once we reach the caucuses\n                break\n\n            committees.append(name)\n            self.scrape_upper_committee(name, link.attrib['href'])\n        return committees\n\n    def scrape_upper_committee(self, name, url):\n        page = self.urlopen(url)\n        page = lxml.html.fromstring(page)\n\n        comm = Committee('upper', name)\n        comm.add_source(url)\n\n        member_div = page.xpath(\"//div[@class = 'committee-members']\")[0]\n\n        seen = set()\n        for link in member_div.xpath(\".//a\"):\n            if not link.text:\n                continue\n\n            member = link.text.strip()\n\n            next_elem = link.getnext()\n            if (next_elem is not None and\n                next_elem.tag == 'a' and\n                next_elem.attrib['href'] == link.attrib['href']):\n                # Sometimes NY is cool and splits names across a\n                # couple links\n                member = \"%s %s\" % (member, next_elem.text.strip())\n\n            member = re.sub(r'\\s+', ' ', member)\n\n            if member in seen or not member:\n                continue\n            seen.add(member)\n\n            name, role = parse_name(member)\n            comm.add_member(name, role)\n\n        self.save_committee(comm)\n", "path": "openstates/ny/committees.py"}], "after_files": [{"content": "import re\n\nfrom billy.scrape import NoDataForPeriod\nfrom billy.scrape.committees import CommitteeScraper, Committee\n\nimport lxml.html\n\n\ndef parse_name(name):\n    \"\"\"\n    Split a committee membership string into name and role.\n\n    >>> parse_name('Felix Ortiz')\n    ('Felix Ortiz', 'member')\n    >>> parse_name('Felix Ortiz (Chair)')\n    ('Felix Ortiz', 'chair')\n    >>> parse_name('Hon. Felix Ortiz, Co-Chair')\n    ('Felix Ortiz', 'co-chair')\n    >>> parse_name('Owen H.\\\\r\\\\nJohnson (Vice Chairperson)')\n    ('Owen H. Johnson', 'vice chairperson')\n    \"\"\"\n    name = re.sub(r'^(Hon\\.|Assemblyman|Assemblywoman)\\s+', '', name)\n    name = re.sub(r'\\s+', ' ', name)\n\n    roles = [\"Chairwoman\", \"Chairperson\", \"Chair\", \"Secretary\", \"Treasurer\",\n             \"Parliamentarian\", \"Chaplain\"]\n    match = re.match(\n        r'([^(]+),? \\(?((Co|Vice)?-?\\s*(%s))\\)?' % '|'.join(roles),\n        name)\n\n    if match:\n        name = match.group(1).strip(' ,')\n        role = match.group(2).lower()\n        return (name, role)\n    return (name, 'member')\n\n\nclass NYCommitteeScraper(CommitteeScraper):\n    state = \"ny\"\n    latest_only = True\n\n    def scrape(self, chamber, term):\n        getattr(self, 'scrape_' + chamber)()\n\n    def scrape_lower(self, only_names=None):\n        committees = []\n        url = \"http://assembly.state.ny.us/comm/\"\n        page = self.urlopen(url)\n        page = lxml.html.fromstring(page)\n        page.make_links_absolute(url)\n\n        for link in page.xpath(\"//a[contains(@href, 'sec=mem')]\"):\n            name = link.xpath(\"string(../strong)\").strip()\n            if 'Caucus' in name:\n                continue\n\n            url = link.attrib['href']\n\n            committees.append(name)\n\n            self.scrape_lower_committee(name, url)\n        return committees\n\n    def scrape_lower_committee(self, name, url):\n        page = self.urlopen(url)\n        page = lxml.html.fromstring(page)\n\n        comm = Committee('lower', name)\n        comm.add_source(url)\n\n        for link in page.xpath(\"//div[@class='commlinks']//a[contains(@href, 'mem')]\"):\n            member = link.text.strip()\n            member = re.sub(r'\\s+', ' ', member)\n\n            name, role = parse_name(member)\n            comm.add_member(name, role)\n\n        self.save_committee(comm)\n\n    def scrape_upper(self):\n        committees = []\n        url = \"http://www.nysenate.gov/committees\"\n        page = self.urlopen(url)\n        page = lxml.html.fromstring(page)\n        page.make_links_absolute(url)\n\n        for h2 in page.xpath(\"//h2\"):\n            committee_types = ['Standing Committees','Temporary Committees']\n            if h2.text not in committee_types:\n                continue\n            \n            for link in h2.getparent().xpath(\".//a[contains(@href, '/committee/')]\"):\n                name = link.text.strip()\n\n                committees.append(name)\n                self.scrape_upper_committee(name, link.attrib['href'])\n\n        return committees\n\n    def scrape_upper_committee(self, name, url):\n        page = self.urlopen(url)\n        page = lxml.html.fromstring(page)\n\n        comm = Committee('upper', name)\n        comm.add_source(url)\n\n        member_div = page.xpath(\"//div[@class = 'committee-members']\")[0]\n\n        seen = set()\n        for link in member_div.xpath(\".//a\"):\n            if not link.text:\n                continue\n\n            member = link.text.strip()\n\n            next_elem = link.getnext()\n            if (next_elem is not None and\n                next_elem.tag == 'a' and\n                next_elem.attrib['href'] == link.attrib['href']):\n                # Sometimes NY is cool and splits names across a\n                # couple links\n                member = \"%s %s\" % (member, next_elem.text.strip())\n\n            member = re.sub(r'\\s+', ' ', member)\n\n            if member in seen or not member:\n                continue\n            seen.add(member)\n\n            name, role = parse_name(member)\n            comm.add_member(name, role)\n\n        self.save_committee(comm)\n", "path": "openstates/ny/committees.py"}]}