Repository: openstates/openstates-scrapers

Issue:
OK scraper failing since at least 2017-02-28
State: OK - scraper has been failing since 2017-02-28

Based on automated runs it appears that OK has not run successfully in 4 days (2017-02-28).

```/usr/local/bin/billy-update ok``` | **failed during legislators**

```
  Traceback (most recent call last):
  File "/opt/openstates/billy/billy/bin/update.py", line 380, in main
    run_record += _run_scraper(stype, args, metadata)
  File "/opt/openstates/billy/billy/bin/update.py", line 104, in _run_scraper
    scraper.scrape(chamber, time)
  File "/srv/openstates-web/openstates/ok/legislators.py", line 62, in scrape
    getattr(self, 'scrape_' + chamber + '_chamber')(term)
  File "/srv/openstates-web/openstates/ok/legislators.py", line 108, in scrape_lower_chamber
    party = self._parties[party_text]
KeyError: ''

```

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



Discussion:

Resolving patch:
diff --git a/openstates/ok/legislators.py b/openstates/ok/legislators.py
--- a/openstates/ok/legislators.py
+++ b/openstates/ok/legislators.py
@@ -20,9 +20,9 @@ def _clean_office_info(self, office_info):
         # address lines.
         while office_info:
             last = office_info[-1]
-            if '@' not in last \
-                and ', OK' not in last \
-                and not re.search(r'[\d\-\(\) ]{7,}', last):
+            if ('@' not in last
+                    and ', OK' not in last
+                    and not re.search(r'[\d\-\(\) ]{7,}', last)):
                 office_info.pop()
             else:
                 break
@@ -57,7 +57,6 @@ def _extract_email(self, doc):
 
         return email if validate_email_address(email) else ''
 
-
     def scrape(self, chamber, term):
         getattr(self, 'scrape_' + chamber + '_chamber')(term)
 
@@ -78,6 +77,10 @@ def scrape_lower_chamber(self, term):
             if name_node is not None:
                 name_text = name_node.text.strip()
 
+                # Handle seats with no current representative
+                if re.search(r'District \d+', name_text):
+                    continue
+
                 last_name, delimiter, first_name = name_text.partition(',')
 
                 if last_name is not None and first_name is not None:
@@ -174,7 +177,7 @@ def scrape_lower_offices(self, doc, legislator):
         # District offices only have address, no other information
         district_address = doc.xpath('//span[@id="ctl00_ContentPlaceHolder1_lblDistrictAddress"]/text()')
         if district_address:
-            (district_city_state, ) = doc.xpath('//span[@id="ctl00_ContentPlaceHolder1_lblDistrictCity"]/text()')
+            district_city_state,  = doc.xpath('//span[@id="ctl00_ContentPlaceHolder1_lblDistrictCity"]/text()')
             district_address = "{}\n{}".format(district_address[0], district_city_state)
 
             office = dict(name='District Office', type='district', address=district_address)
@@ -193,7 +196,7 @@ def scrape_upper_chamber(self, term):
             else:
                 district = a.xpath('../../span')[1].text.split()[1]
 
-            if a.text == None:
+            if a.text is None:
                 self.warning("District {} appears to be empty".format(district))
                 continue
             else:
@@ -207,8 +210,6 @@ def scrape_upper_chamber(self, term):
             self.scrape_upper_offices(leg, url)
             self.save_legislator(leg)
 
-
-
     def scrape_upper_offices(self, legislator, url):
         url = url.replace('aspx', 'html')
         html = self.get(url).text
@@ -268,7 +269,7 @@ def scrape_upper_offices(self, legislator, url):
                 district_address_lines))
         else:
             district_address = None
-        #self.logger.debug(district_address)
+        # self.logger.debug(district_address)
 
         district_phone = self._extract_phone(district_office_info)
 


Test patch: