We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
MI scraper failing since at least 2017-04-01
MI has been failing since 2017-04-01

Based on automated runs it appears that MI has not run successfully in 5 days (2017-04-01).


```
  06:00:31 INFO billy: billy-update abbr=mi
    actions=scrape,import,report
    types=bills,legislators,votes,committees,alldata,events
    sessions=2017-2018
    terms=2017-2018
06:00:31 INFO scrapelib: GET - http://www.senate.michigan.gov/senatorinfo.html
  File "/usr/local/bin/billy-update", line 9, in <module>
    load_entry_point('billy==1.9.0', 'console_scripts', 'billy-update')()
  File "/opt/openstates/billy/billy/bin/update.py", line 368, in main
Traceback (most recent call last):
    run_record += _run_scraper(stype, args, metadata)
  File "/opt/openstates/billy/billy/bin/update.py", line 102, in _run_scraper
    response = self.get(url)
  File "/usr/local/lib/python2.7/dist-packages/requests/sessions.py", line 501, in get
    return self.request('GET', url, **kwargs)
  File "/usr/local/lib/python2.7/dist-packages/scrapelib/__init__.py", line 272, in request
    raise HTTPError(resp)
scrapelib.HTTPError: 500 while retrieving http://www.senate.michigan.gov/senatorinfo.html
  File "/srv/openstates-web/openstates/mi/legislators.py", line 77, in scrape_upper
    scraper.scrape(chamber, time)
  File "/srv/openstates-web/openstates/mi/legislators.py", line 16, in scrape
    return self.scrape_upper(chamber, term)
    doc = self.lxmlize(url)
  File "/srv/openstates-web/openstates/utils/lxmlize.py", line 19, in lxmlize
```

Visit http://bobsled.openstates.org/ for more info.


--- 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/mi/legislators.py`
Content:
```
1 import re
2 
3 from billy.scrape.legislators import LegislatorScraper, Legislator
4 from openstates.utils import LXMLMixin
5 
6 abbr = {'D': 'Democratic', 'R': 'Republican'}
7 
8 
9 class MILegislatorScraper(LegislatorScraper, LXMLMixin):
10     jurisdiction = 'mi'
11 
12     def scrape(self, chamber, term):
13         self.validate_term(term, latest_only=True)
14         if chamber == 'lower':
15             return self.scrape_lower(chamber, term)
16         return self.scrape_upper(chamber, term)
17 
18     def scrape_lower(self, chamber, term):
19         url = 'http://www.house.mi.gov/mhrpublic/frmRepList.aspx'
20         table = [
21             "website",
22             "district",
23             "name",
24             "party",
25             "location",
26             "phone",
27             "email"
28         ]
29         doc = self.lxmlize(url)
30         # skip two rows at top
31         for row in doc.xpath('//table[@id="grvRepInfo"]/*'):
32             tds = row.xpath('.//td')
33             if len(tds) == 0:
34                 continue
35             metainf = {}
36             for i in range(0, len(table)):
37                 metainf[table[i]] = tds[i]
38             district = str(int(metainf['district'].text_content().strip()))
39             party = metainf['party'].text_content().strip()
40             phone = metainf['phone'].text_content().strip()
41             email = metainf['email'].text_content().strip()
42             leg_url = metainf['website'].xpath("./a")[0].attrib['href']
43             name = metainf['name'].text_content().strip()
44             if name == 'Vacant' or re.match(r'^District \d{1,3}$', name):
45                 self.warning('District {} appears vacant, and will be skipped'.format(district))
46                 continue
47 
48             office = metainf['location'].text_content().strip()
49             office = re.sub(
50                     ' HOB',
51                     ' Anderson House Office Building\n124 North Capitol Avenue\nLansing, MI 48933',
52                     office
53                     )
54             office = re.sub(
55                     ' CB',
56                     ' State Capitol Building\nLansing, MI 48909',
57                     office
58                     )
59 
60             leg = Legislator(term=term,
61                              chamber=chamber,
62                              full_name=name,
63                              district=district,
64                              party=abbr[party],
65                              url=leg_url)
66 
67             leg.add_office('capitol', 'Capitol Office',
68                            address=office,
69                            phone=phone,
70                            email=email)
71 
72             leg.add_source(url)
73             self.save_legislator(leg)
74 
75     def scrape_upper(self, chamber, term):
76         url = 'http://www.senate.michigan.gov/senatorinfo.html'
77         doc = self.lxmlize(url)
78         for row in doc.xpath('//table[not(@class="calendar")]//tr')[3:]:
79             if len(row) != 7:
80                 continue
81 
82             # party, dist, member, office_phone, office_fax, office_loc
83             party, dist, member, contact, phone, fax, loc = row.getchildren()
84             if (party.text_content().strip() == "" or
85                     'Lieutenant Governor' in member.text_content()):
86                 continue
87 
88             party = abbr[party.text]
89             district = dist.text_content().strip()
90             name = member.text_content().strip()
91             name = re.sub(r'\s+', " ", name)
92 
93             if name == 'Vacant':
94                 self.info('district %s is vacant', district)
95                 continue
96 
97             leg_url = member.xpath('a/@href')[0]
98             office_phone = phone.text
99             office_fax = fax.text
100 
101             office_loc = loc.text
102             office_loc = re.sub(
103                     ' Farnum Bldg',
104                     ' Farnum Office Building\n125 West Allegan Street\nLansing, MI 48933',
105                     office_loc
106                     )
107             office_loc = re.sub(
108                     ' Capitol Bldg',
109                     ' State Capitol Building\nLansing, MI 48909',
110                     office_loc
111                     )
112 
113             leg = Legislator(term=term, chamber=chamber,
114                              district=district,
115                              full_name=name,
116                              party=party,
117                              url=leg_url)
118 
119             leg.add_office('capitol', 'Capitol Office',
120                            address=office_loc,
121                            fax=office_fax,
122                            phone=office_phone)
123 
124             leg.add_source(url)
125             self.save_legislator(leg)
126
```
--- 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()

```

diff --git a/openstates/mi/legislators.py b/openstates/mi/legislators.py
--- a/openstates/mi/legislators.py
+++ b/openstates/mi/legislators.py
@@ -73,7 +73,7 @@
             self.save_legislator(leg)
 
     def scrape_upper(self, chamber, term):
-        url = 'http://www.senate.michigan.gov/senatorinfo.html'
+        url = 'http://www.senate.michigan.gov/senatorinfo_list.html'
         doc = self.lxmlize(url)
         for row in doc.xpath('//table[not(@class="calendar")]//tr')[3:]:
             if len(row) != 7:

{"golden_diff": "diff --git a/openstates/mi/legislators.py b/openstates/mi/legislators.py\n--- a/openstates/mi/legislators.py\n+++ b/openstates/mi/legislators.py\n@@ -73,7 +73,7 @@\n             self.save_legislator(leg)\n \n     def scrape_upper(self, chamber, term):\n-        url = 'http://www.senate.michigan.gov/senatorinfo.html'\n+        url = 'http://www.senate.michigan.gov/senatorinfo_list.html'\n         doc = self.lxmlize(url)\n         for row in doc.xpath('//table[not(@class=\"calendar\")]//tr')[3:]:\n             if len(row) != 7:\n", "issue": "MI scraper failing since at least 2017-04-01\nMI has been failing since 2017-04-01\n\nBased on automated runs it appears that MI has not run successfully in 5 days (2017-04-01).\n\n\n```\n  06:00:31 INFO billy: billy-update abbr=mi\n    actions=scrape,import,report\n    types=bills,legislators,votes,committees,alldata,events\n    sessions=2017-2018\n    terms=2017-2018\n06:00:31 INFO scrapelib: GET - http://www.senate.michigan.gov/senatorinfo.html\n  File \"/usr/local/bin/billy-update\", line 9, in <module>\n    load_entry_point('billy==1.9.0', 'console_scripts', 'billy-update')()\n  File \"/opt/openstates/billy/billy/bin/update.py\", line 368, in main\nTraceback (most recent call last):\n    run_record += _run_scraper(stype, args, metadata)\n  File \"/opt/openstates/billy/billy/bin/update.py\", line 102, in _run_scraper\n    response = self.get(url)\n  File \"/usr/local/lib/python2.7/dist-packages/requests/sessions.py\", line 501, in get\n    return self.request('GET', url, **kwargs)\n  File \"/usr/local/lib/python2.7/dist-packages/scrapelib/__init__.py\", line 272, in request\n    raise HTTPError(resp)\nscrapelib.HTTPError: 500 while retrieving http://www.senate.michigan.gov/senatorinfo.html\n  File \"/srv/openstates-web/openstates/mi/legislators.py\", line 77, in scrape_upper\n    scraper.scrape(chamber, time)\n  File \"/srv/openstates-web/openstates/mi/legislators.py\", line 16, in scrape\n    return self.scrape_upper(chamber, term)\n    doc = self.lxmlize(url)\n  File \"/srv/openstates-web/openstates/utils/lxmlize.py\", line 19, in lxmlize\n```\n\nVisit http://bobsled.openstates.org/ for more info.\n\n", "before_files": [{"content": "import re\n\nfrom billy.scrape.legislators import LegislatorScraper, Legislator\nfrom openstates.utils import LXMLMixin\n\nabbr = {'D': 'Democratic', 'R': 'Republican'}\n\n\nclass MILegislatorScraper(LegislatorScraper, LXMLMixin):\n    jurisdiction = 'mi'\n\n    def scrape(self, chamber, term):\n        self.validate_term(term, latest_only=True)\n        if chamber == 'lower':\n            return self.scrape_lower(chamber, term)\n        return self.scrape_upper(chamber, term)\n\n    def scrape_lower(self, chamber, term):\n        url = 'http://www.house.mi.gov/mhrpublic/frmRepList.aspx'\n        table = [\n            \"website\",\n            \"district\",\n            \"name\",\n            \"party\",\n            \"location\",\n            \"phone\",\n            \"email\"\n        ]\n        doc = self.lxmlize(url)\n        # skip two rows at top\n        for row in doc.xpath('//table[@id=\"grvRepInfo\"]/*'):\n            tds = row.xpath('.//td')\n            if len(tds) == 0:\n                continue\n            metainf = {}\n            for i in range(0, len(table)):\n                metainf[table[i]] = tds[i]\n            district = str(int(metainf['district'].text_content().strip()))\n            party = metainf['party'].text_content().strip()\n            phone = metainf['phone'].text_content().strip()\n            email = metainf['email'].text_content().strip()\n            leg_url = metainf['website'].xpath(\"./a\")[0].attrib['href']\n            name = metainf['name'].text_content().strip()\n            if name == 'Vacant' or re.match(r'^District \\d{1,3}$', name):\n                self.warning('District {} appears vacant, and will be skipped'.format(district))\n                continue\n\n            office = metainf['location'].text_content().strip()\n            office = re.sub(\n                    ' HOB',\n                    ' Anderson House Office Building\\n124 North Capitol Avenue\\nLansing, MI 48933',\n                    office\n                    )\n            office = re.sub(\n                    ' CB',\n                    ' State Capitol Building\\nLansing, MI 48909',\n                    office\n                    )\n\n            leg = Legislator(term=term,\n                             chamber=chamber,\n                             full_name=name,\n                             district=district,\n                             party=abbr[party],\n                             url=leg_url)\n\n            leg.add_office('capitol', 'Capitol Office',\n                           address=office,\n                           phone=phone,\n                           email=email)\n\n            leg.add_source(url)\n            self.save_legislator(leg)\n\n    def scrape_upper(self, chamber, term):\n        url = 'http://www.senate.michigan.gov/senatorinfo.html'\n        doc = self.lxmlize(url)\n        for row in doc.xpath('//table[not(@class=\"calendar\")]//tr')[3:]:\n            if len(row) != 7:\n                continue\n\n            # party, dist, member, office_phone, office_fax, office_loc\n            party, dist, member, contact, phone, fax, loc = row.getchildren()\n            if (party.text_content().strip() == \"\" or\n                    'Lieutenant Governor' in member.text_content()):\n                continue\n\n            party = abbr[party.text]\n            district = dist.text_content().strip()\n            name = member.text_content().strip()\n            name = re.sub(r'\\s+', \" \", name)\n\n            if name == 'Vacant':\n                self.info('district %s is vacant', district)\n                continue\n\n            leg_url = member.xpath('a/@href')[0]\n            office_phone = phone.text\n            office_fax = fax.text\n\n            office_loc = loc.text\n            office_loc = re.sub(\n                    ' Farnum Bldg',\n                    ' Farnum Office Building\\n125 West Allegan Street\\nLansing, MI 48933',\n                    office_loc\n                    )\n            office_loc = re.sub(\n                    ' Capitol Bldg',\n                    ' State Capitol Building\\nLansing, MI 48909',\n                    office_loc\n                    )\n\n            leg = Legislator(term=term, chamber=chamber,\n                             district=district,\n                             full_name=name,\n                             party=party,\n                             url=leg_url)\n\n            leg.add_office('capitol', 'Capitol Office',\n                           address=office_loc,\n                           fax=office_fax,\n                           phone=office_phone)\n\n            leg.add_source(url)\n            self.save_legislator(leg)\n", "path": "openstates/mi/legislators.py"}], "after_files": [{"content": "import re\n\nfrom billy.scrape.legislators import LegislatorScraper, Legislator\nfrom openstates.utils import LXMLMixin\n\nabbr = {'D': 'Democratic', 'R': 'Republican'}\n\n\nclass MILegislatorScraper(LegislatorScraper, LXMLMixin):\n    jurisdiction = 'mi'\n\n    def scrape(self, chamber, term):\n        self.validate_term(term, latest_only=True)\n        if chamber == 'lower':\n            return self.scrape_lower(chamber, term)\n        return self.scrape_upper(chamber, term)\n\n    def scrape_lower(self, chamber, term):\n        url = 'http://www.house.mi.gov/mhrpublic/frmRepList.aspx'\n        table = [\n            \"website\",\n            \"district\",\n            \"name\",\n            \"party\",\n            \"location\",\n            \"phone\",\n            \"email\"\n        ]\n        doc = self.lxmlize(url)\n        # skip two rows at top\n        for row in doc.xpath('//table[@id=\"grvRepInfo\"]/*'):\n            tds = row.xpath('.//td')\n            if len(tds) == 0:\n                continue\n            metainf = {}\n            for i in range(0, len(table)):\n                metainf[table[i]] = tds[i]\n            district = str(int(metainf['district'].text_content().strip()))\n            party = metainf['party'].text_content().strip()\n            phone = metainf['phone'].text_content().strip()\n            email = metainf['email'].text_content().strip()\n            leg_url = metainf['website'].xpath(\"./a\")[0].attrib['href']\n            name = metainf['name'].text_content().strip()\n            if name == 'Vacant' or re.match(r'^District \\d{1,3}$', name):\n                self.warning('District {} appears vacant, and will be skipped'.format(district))\n                continue\n\n            office = metainf['location'].text_content().strip()\n            office = re.sub(\n                    ' HOB',\n                    ' Anderson House Office Building\\n124 North Capitol Avenue\\nLansing, MI 48933',\n                    office\n                    )\n            office = re.sub(\n                    ' CB',\n                    ' State Capitol Building\\nLansing, MI 48909',\n                    office\n                    )\n\n            leg = Legislator(term=term,\n                             chamber=chamber,\n                             full_name=name,\n                             district=district,\n                             party=abbr[party],\n                             url=leg_url)\n\n            leg.add_office('capitol', 'Capitol Office',\n                           address=office,\n                           phone=phone,\n                           email=email)\n\n            leg.add_source(url)\n            self.save_legislator(leg)\n\n    def scrape_upper(self, chamber, term):\n        url = 'http://www.senate.michigan.gov/senatorinfo_list.html'\n        doc = self.lxmlize(url)\n        for row in doc.xpath('//table[not(@class=\"calendar\")]//tr')[3:]:\n            if len(row) != 7:\n                continue\n\n            # party, dist, member, office_phone, office_fax, office_loc\n            party, dist, member, contact, phone, fax, loc = row.getchildren()\n            if (party.text_content().strip() == \"\" or\n                    'Lieutenant Governor' in member.text_content()):\n                continue\n\n            party = abbr[party.text]\n            district = dist.text_content().strip()\n            name = member.text_content().strip()\n            name = re.sub(r'\\s+', \" \", name)\n\n            if name == 'Vacant':\n                self.info('district %s is vacant', district)\n                continue\n\n            leg_url = member.xpath('a/@href')[0]\n            office_phone = phone.text\n            office_fax = fax.text\n\n            office_loc = loc.text\n            office_loc = re.sub(\n                    ' Farnum Bldg',\n                    ' Farnum Office Building\\n125 West Allegan Street\\nLansing, MI 48933',\n                    office_loc\n                    )\n            office_loc = re.sub(\n                    ' Capitol Bldg',\n                    ' State Capitol Building\\nLansing, MI 48909',\n                    office_loc\n                    )\n\n            leg = Legislator(term=term, chamber=chamber,\n                             district=district,\n                             full_name=name,\n                             party=party,\n                             url=leg_url)\n\n            leg.add_office('capitol', 'Capitol Office',\n                           address=office_loc,\n                           fax=office_fax,\n                           phone=office_phone)\n\n            leg.add_source(url)\n            self.save_legislator(leg)\n", "path": "openstates/mi/legislators.py"}]}