prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  Spider kopps is broken
  During the global build at 2021-06-16-14-42-20, spider **kopps** failed with **0 features** and **1 errors**.
  
  Here's [the log](https://data.alltheplaces.xyz/runs/2021-06-16-14-42-20/logs/kopps.txt) and [the output](https://data.alltheplaces.xyz/runs/2021-06-16-14-42-20/output/kopps.geojson) ([on a map](https://data.alltheplaces.xyz/map.html?show=https://data.alltheplaces.xyz/runs/2021-06-16-14-42-20/output/kopps.geojson))
  
  --- END ISSUE ---
  
  Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
  --- BEGIN FILES ---
  Path: `locations/spiders/kopps.py`
  Content:
  ```
  1 import scrapy
  2 import re
  3 from locations.items import GeojsonPointItem
  4 
  5 DAY_MAPPING = {
  6     "Mon": "Mo",
  7     "Tues": "Tu",
  8     "Wed": "We",
  9     "Thur": "Th",
  10     "Fri": "Fr",
  11     "Sat": "Sa",
  12     "Sun": "Su"
  13 }
  14 class KoppsSpider(scrapy.Spider):
  15     name = "kopps"
  16     item_attributes = { 'brand': "Kopps" }
  17     allowed_domains = ["www.kopps.com"]
  18     download_delay = 1.5
  19     start_urls = (
  20         'https://www.kopps.com/',
  21     )
  22 
  23     def parse_day(self, day):
  24         if re.search('-', day):
  25             days = day.split('-')
  26             osm_days = []
  27             if len(days) == 2:
  28                 for day in days:
  29                     osm_day = DAY_MAPPING[day.strip()]
  30                     osm_days.append(osm_day)
  31             return "-".join(osm_days)
  32 
  33     def parse_times(self, times):
  34         if times.strip() == 'Open 24 hours':
  35             return '24/7'
  36         hours_to = [x.strip() for x in times.split('-')]
  37         cleaned_times = []
  38 
  39         for hour in hours_to:
  40             if re.search('pm$', hour):
  41                 hour = re.sub('pm', '', hour).strip()
  42                 hour_min = hour.split(":")
  43                 if int(hour_min[0]) < 12:
  44                     hour_min[0] = str(12 + int(hour_min[0]))
  45                 cleaned_times.append(":".join(hour_min))
  46 
  47             if re.search('am$', hour):
  48                 hour = re.sub('am', '', hour).strip()
  49                 hour_min = hour.split(":")
  50                 if len(hour_min[0]) <2:
  51                     hour_min[0] = hour_min[0].zfill(2)
  52                 else:
  53                     hour_min[0] = str( int(hour_min[0]))
  54 
  55                 cleaned_times.append(":".join(hour_min))
  56         return "-".join(cleaned_times)
  57 
  58     def parse_hours(self, lis):
  59         hours = []
  60         for li in lis:
  61             day_times = li.xpath('normalize-space(./text())').extract_first()
  62             day = re.findall(r"^[a-zA-Z-]+" , day_times)
  63             if(len(day)>0):
  64                 day = day[0]
  65             else:
  66                 day = 'Mon-Sun'
  67             times =  re.findall(r"[0-9]{2}:[0-9]{2}[a|p]m - [0-9]{2}:[0-9]{2}[a|p]m" ,day_times)
  68             times =  times[0]
  69             if times and day:
  70                 parsed_time = self.parse_times(times)
  71                 parsed_day = self.parse_day(day)
  72                 hours.append(parsed_day + ' ' + parsed_time)
  73 
  74         return "; ".join(hours)
  75 
  76 
  77     def parse(self, response):
  78         locations = response.xpath('//div[@id="locations"]/div/div')
  79 
  80         for location in locations:
  81             properties = {
  82                 'addr_full': location.xpath('normalize-space(./div/address/a/text())').extract_first(),
  83                 'phone': location.xpath('normalize-space(./div/ul/li/span/a/text())').extract_first(),
  84                 'city': location.xpath('./div/address/a/text()').extract()[1].replace(' ' ,'').split(',')[0].replace('\r\n' ,''),
  85                 'state':  location.xpath('./div/address/a/text()').extract()[1].lstrip().split(',')[1].split(' ')[1],
  86                 'postcode': location.xpath('./div/address/a/text()').extract()[1].lstrip().split(',')[1].split(' ')[2].replace('\r\n' ,''),
  87                 'ref': location.xpath('normalize-space(./div/address/a/@href)').extract_first(),
  88                 'website': response.url,
  89                 'lat':re.findall(r"\/[0-9]{2}[^(\/)]+z",location.xpath('normalize-space(./div/address/a/@href)').extract_first())[0][1:].split(',')[0],
  90                 'lon': re.findall(r"\/[0-9]{2}[^(\/)]+z",location.xpath('normalize-space(./div/address/a/@href)').extract_first())[0][1:].split(',')[1],
  91             }
  92 
  93             hours = self.parse_hours(location.xpath('./div/ul/li[3]/span'))
  94             if hours:
  95                 properties['opening_hours'] = hours
  96 
  97             yield GeojsonPointItem(**properties)
  ```
  --- 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/locations/spiders/kopps.py b/locations/spiders/kopps.py
  --- a/locations/spiders/kopps.py
  +++ b/locations/spiders/kopps.py
  @@ -26,8 +26,9 @@
               osm_days = []
               if len(days) == 2:
                   for day in days:
  -                    osm_day = DAY_MAPPING[day.strip()]
  -                    osm_days.append(osm_day)
  +                    if day.strip() in DAY_MAPPING:
  +                        osm_day = DAY_MAPPING[day.strip()]
  +                        osm_days.append(osm_day)
               return "-".join(osm_days)
   
       def parse_times(self, times):
  @@ -69,7 +70,8 @@
               if times and day:
                   parsed_time = self.parse_times(times)
                   parsed_day = self.parse_day(day)
  -                hours.append(parsed_day + ' ' + parsed_time)
  +                if parsed_day and parsed_time:
  +                    hours.append(parsed_day + ' ' + parsed_time)
   
           return "; ".join(hours)
  
verification_info: {"golden_diff": "diff --git a/locations/spiders/kopps.py b/locations/spiders/kopps.py\n--- a/locations/spiders/kopps.py\n+++ b/locations/spiders/kopps.py\n@@ -26,8 +26,9 @@\n             osm_days = []\n             if len(days) == 2:\n                 for day in days:\n-                    osm_day = DAY_MAPPING[day.strip()]\n-                    osm_days.append(osm_day)\n+                    if day.strip() in DAY_MAPPING:\n+                        osm_day = DAY_MAPPING[day.strip()]\n+                        osm_days.append(osm_day)\n             return \"-\".join(osm_days)\n \n     def parse_times(self, times):\n@@ -69,7 +70,8 @@\n             if times and day:\n                 parsed_time = self.parse_times(times)\n                 parsed_day = self.parse_day(day)\n-                hours.append(parsed_day + ' ' + parsed_time)\n+                if parsed_day and parsed_time:\n+                    hours.append(parsed_day + ' ' + parsed_time)\n \n         return \"; \".join(hours)\n", "issue": "Spider kopps is broken\nDuring the global build at 2021-06-16-14-42-20, spider **kopps** failed with **0 features** and **1 errors**.\n\nHere's [the log](https://data.alltheplaces.xyz/runs/2021-06-16-14-42-20/logs/kopps.txt) and [the output](https://data.alltheplaces.xyz/runs/2021-06-16-14-42-20/output/kopps.geojson) ([on a map](https://data.alltheplaces.xyz/map.html?show=https://data.alltheplaces.xyz/runs/2021-06-16-14-42-20/output/kopps.geojson))\n", "before_files": [{"content": "import scrapy\nimport re\nfrom locations.items import GeojsonPointItem\n\nDAY_MAPPING = {\n    \"Mon\": \"Mo\",\n    \"Tues\": \"Tu\",\n    \"Wed\": \"We\",\n    \"Thur\": \"Th\",\n    \"Fri\": \"Fr\",\n    \"Sat\": \"Sa\",\n    \"Sun\": \"Su\"\n}\nclass KoppsSpider(scrapy.Spider):\n    name = \"kopps\"\n    item_attributes = { 'brand': \"Kopps\" }\n    allowed_domains = [\"www.kopps.com\"]\n    download_delay = 1.5\n    start_urls = (\n        'https://www.kopps.com/',\n    )\n\n    def parse_day(self, day):\n        if re.search('-', day):\n            days = day.split('-')\n            osm_days = []\n            if len(days) == 2:\n                for day in days:\n                    osm_day = DAY_MAPPING[day.strip()]\n                    osm_days.append(osm_day)\n            return \"-\".join(osm_days)\n\n    def parse_times(self, times):\n        if times.strip() == 'Open 24 hours':\n            return '24/7'\n        hours_to = [x.strip() for x in times.split('-')]\n        cleaned_times = []\n\n        for hour in hours_to:\n            if re.search('pm$', hour):\n                hour = re.sub('pm', '', hour).strip()\n                hour_min = hour.split(\":\")\n                if int(hour_min[0]) < 12:\n                    hour_min[0] = str(12 + int(hour_min[0]))\n                cleaned_times.append(\":\".join(hour_min))\n\n            if re.search('am$', hour):\n                hour = re.sub('am', '', hour).strip()\n                hour_min = hour.split(\":\")\n                if len(hour_min[0]) <2:\n                    hour_min[0] = hour_min[0].zfill(2)\n                else:\n                    hour_min[0] = str( int(hour_min[0]))\n\n                cleaned_times.append(\":\".join(hour_min))\n        return \"-\".join(cleaned_times)\n\n    def parse_hours(self, lis):\n        hours = []\n        for li in lis:\n            day_times = li.xpath('normalize-space(./text())').extract_first()\n            day = re.findall(r\"^[a-zA-Z-]+\" , day_times)\n            if(len(day)>0):\n                day = day[0]\n            else:\n                day = 'Mon-Sun'\n            times =  re.findall(r\"[0-9]{2}:[0-9]{2}[a|p]m - [0-9]{2}:[0-9]{2}[a|p]m\" ,day_times)\n            times =  times[0]\n            if times and day:\n                parsed_time = self.parse_times(times)\n                parsed_day = self.parse_day(day)\n                hours.append(parsed_day + ' ' + parsed_time)\n\n        return \"; \".join(hours)\n\n\n    def parse(self, response):\n        locations = response.xpath('//div[@id=\"locations\"]/div/div')\n\n        for location in locations:\n            properties = {\n                'addr_full': location.xpath('normalize-space(./div/address/a/text())').extract_first(),\n                'phone': location.xpath('normalize-space(./div/ul/li/span/a/text())').extract_first(),\n                'city': location.xpath('./div/address/a/text()').extract()[1].replace(' ' ,'').split(',')[0].replace('\\r\\n' ,''),\n                'state':  location.xpath('./div/address/a/text()').extract()[1].lstrip().split(',')[1].split(' ')[1],\n                'postcode': location.xpath('./div/address/a/text()').extract()[1].lstrip().split(',')[1].split(' ')[2].replace('\\r\\n' ,''),\n                'ref': location.xpath('normalize-space(./div/address/a/@href)').extract_first(),\n                'website': response.url,\n                'lat':re.findall(r\"\\/[0-9]{2}[^(\\/)]+z\",location.xpath('normalize-space(./div/address/a/@href)').extract_first())[0][1:].split(',')[0],\n                'lon': re.findall(r\"\\/[0-9]{2}[^(\\/)]+z\",location.xpath('normalize-space(./div/address/a/@href)').extract_first())[0][1:].split(',')[1],\n            }\n\n            hours = self.parse_hours(location.xpath('./div/ul/li[3]/span'))\n            if hours:\n                properties['opening_hours'] = hours\n\n            yield GeojsonPointItem(**properties)", "path": "locations/spiders/kopps.py"}], "after_files": [{"content": "import scrapy\nimport re\nfrom locations.items import GeojsonPointItem\n\nDAY_MAPPING = {\n    \"Mon\": \"Mo\",\n    \"Tues\": \"Tu\",\n    \"Wed\": \"We\",\n    \"Thur\": \"Th\",\n    \"Fri\": \"Fr\",\n    \"Sat\": \"Sa\",\n    \"Sun\": \"Su\"\n}\nclass KoppsSpider(scrapy.Spider):\n    name = \"kopps\"\n    item_attributes = { 'brand': \"Kopps\" }\n    allowed_domains = [\"www.kopps.com\"]\n    download_delay = 1.5\n    start_urls = (\n        'https://www.kopps.com/',\n    )\n\n    def parse_day(self, day):\n        if re.search('-', day):\n            days = day.split('-')\n            osm_days = []\n            if len(days) == 2:\n                for day in days:\n                    if day.strip() in DAY_MAPPING:\n                        osm_day = DAY_MAPPING[day.strip()]\n                        osm_days.append(osm_day)\n            return \"-\".join(osm_days)\n\n    def parse_times(self, times):\n        if times.strip() == 'Open 24 hours':\n            return '24/7'\n        hours_to = [x.strip() for x in times.split('-')]\n        cleaned_times = []\n\n        for hour in hours_to:\n            if re.search('pm$', hour):\n                hour = re.sub('pm', '', hour).strip()\n                hour_min = hour.split(\":\")\n                if int(hour_min[0]) < 12:\n                    hour_min[0] = str(12 + int(hour_min[0]))\n                cleaned_times.append(\":\".join(hour_min))\n\n            if re.search('am$', hour):\n                hour = re.sub('am', '', hour).strip()\n                hour_min = hour.split(\":\")\n                if len(hour_min[0]) <2:\n                    hour_min[0] = hour_min[0].zfill(2)\n                else:\n                    hour_min[0] = str( int(hour_min[0]))\n\n                cleaned_times.append(\":\".join(hour_min))\n        return \"-\".join(cleaned_times)\n\n    def parse_hours(self, lis):\n        hours = []\n        for li in lis:\n            day_times = li.xpath('normalize-space(./text())').extract_first()\n            day = re.findall(r\"^[a-zA-Z-]+\" , day_times)\n            if(len(day)>0):\n                day = day[0]\n            else:\n                day = 'Mon-Sun'\n            times =  re.findall(r\"[0-9]{2}:[0-9]{2}[a|p]m - [0-9]{2}:[0-9]{2}[a|p]m\" ,day_times)\n            times =  times[0]\n            if times and day:\n                parsed_time = self.parse_times(times)\n                parsed_day = self.parse_day(day)\n                if parsed_day and parsed_time:\n                    hours.append(parsed_day + ' ' + parsed_time)\n\n        return \"; \".join(hours)\n\n\n    def parse(self, response):\n        locations = response.xpath('//div[@id=\"locations\"]/div/div')\n\n        for location in locations:\n            properties = {\n                'addr_full': location.xpath('normalize-space(./div/address/a/text())').extract_first(),\n                'phone': location.xpath('normalize-space(./div/ul/li/span/a/text())').extract_first(),\n                'city': location.xpath('./div/address/a/text()').extract()[1].replace(' ' ,'').split(',')[0].replace('\\r\\n' ,''),\n                'state':  location.xpath('./div/address/a/text()').extract()[1].lstrip().split(',')[1].split(' ')[1],\n                'postcode': location.xpath('./div/address/a/text()').extract()[1].lstrip().split(',')[1].split(' ')[2].replace('\\r\\n' ,''),\n                'ref': location.xpath('normalize-space(./div/address/a/@href)').extract_first(),\n                'website': response.url,\n                'lat':re.findall(r\"\\/[0-9]{2}[^(\\/)]+z\",location.xpath('normalize-space(./div/address/a/@href)').extract_first())[0][1:].split(',')[0],\n                'lon': re.findall(r\"\\/[0-9]{2}[^(\\/)]+z\",location.xpath('normalize-space(./div/address/a/@href)').extract_first())[0][1:].split(',')[1],\n            }\n\n            hours = self.parse_hours(location.xpath('./div/ul/li[3]/span'))\n            if hours:\n                properties['opening_hours'] = hours\n\n            yield GeojsonPointItem(**properties)", "path": "locations/spiders/kopps.py"}]}