prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  Spider planned_parenthood is broken
  During the global build at 2021-05-26-14-42-23, spider **planned_parenthood** failed with **598 features** and **598 errors**.
  
  Here's [the log](https://data.alltheplaces.xyz/runs/2021-05-26-14-42-23/logs/planned_parenthood.log) and [the output](https://data.alltheplaces.xyz/runs/2021-05-26-14-42-23/output/planned_parenthood.geojson) ([on a map](https://data.alltheplaces.xyz/map.html?show=https://data.alltheplaces.xyz/runs/2021-05-26-14-42-23/output/planned_parenthood.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/planned_parenthood.py`
  Content:
  ```
  1 # -*- coding: utf-8 -*-
  2 import scrapy
  3 import re
  4 
  5 from locations.items import GeojsonPointItem
  6 
  7 
  8 class PlannedParenthoodSpider(scrapy.Spider):
  9     name = "planned_parenthood"
  10     item_attributes = { 'brand': "Planned Parenthood" }
  11     allowed_domains = ["www.plannedparenthood.org"]
  12     start_urls = (
  13         'https://www.plannedparenthood.org/health-center',
  14     )
  15 
  16     def parse(self, response):
  17         state_urls = response.xpath('//ul[@class="quicklist-list"]/li/a/@href').extract()
  18         for path in state_urls:
  19             yield scrapy.Request(
  20                 response.urljoin(path),
  21                 callback=self.parse_state,
  22             )
  23 
  24     def parse_state(self, response):
  25         venue_urls = response.xpath('//ul[@class="quicklist-list"]/li/p/a/@href').extract()
  26         for path in venue_urls:
  27             yield scrapy.Request(
  28                 response.urljoin(path),
  29                 callback=self.parse_venue,
  30             )
  31 
  32     def parse_venue(self, response):
  33         properties = {
  34             'addr_full': response.xpath('//*[@itemprop="streetAddress"]/text()').extract_first(),
  35             'city': response.xpath('//*[@itemprop="addressLocality"]/text()').extract_first(),
  36             'state': response.xpath('//*[@itemprop="addressRegion"]/text()').extract_first(),
  37             'postcode': response.xpath('//*[@itemprop="postalCode"]/text()').extract_first(),
  38             'phone': response.xpath('//a[@itemprop="telephone"][@data-link]/text()').extract_first(),
  39             'ref': response.url,
  40             'website': response.url,
  41         }
  42 
  43         map_image_url = response.xpath('//img[@class="address-map"]/@src').extract_first()
  44         match = re.search(r"center=(.*?),(.*?)&zoom", map_image_url)
  45         properties['lat'] = float(match.group(1)),
  46         properties['lon'] = float(match.group(2)),
  47 
  48         yield GeojsonPointItem(**properties)
  49
  ```
  --- 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/planned_parenthood.py b/locations/spiders/planned_parenthood.py
  --- a/locations/spiders/planned_parenthood.py
  +++ b/locations/spiders/planned_parenthood.py
  @@ -27,9 +27,14 @@
               yield scrapy.Request(
                   response.urljoin(path),
                   callback=self.parse_venue,
  +                meta={'dont_redirect':True}
               )
   
       def parse_venue(self, response):
  +        if response is None:
  +            # Ignoring redirects
  +            return
  +
           properties = {
               'addr_full': response.xpath('//*[@itemprop="streetAddress"]/text()').extract_first(),
               'city': response.xpath('//*[@itemprop="addressLocality"]/text()').extract_first(),
  @@ -42,7 +47,7 @@
   
           map_image_url = response.xpath('//img[@class="address-map"]/@src').extract_first()
           match = re.search(r"center=(.*?),(.*?)&zoom", map_image_url)
  -        properties['lat'] = float(match.group(1)),
  -        properties['lon'] = float(match.group(2)),
  +        properties['lat'] = float(match.group(1))
  +        properties['lon'] = float(match.group(2))
   
           yield GeojsonPointItem(**properties)
  
verification_info: {"golden_diff": "diff --git a/locations/spiders/planned_parenthood.py b/locations/spiders/planned_parenthood.py\n--- a/locations/spiders/planned_parenthood.py\n+++ b/locations/spiders/planned_parenthood.py\n@@ -27,9 +27,14 @@\n             yield scrapy.Request(\n                 response.urljoin(path),\n                 callback=self.parse_venue,\n+                meta={'dont_redirect':True}\n             )\n \n     def parse_venue(self, response):\n+        if response is None:\n+            # Ignoring redirects\n+            return\n+\n         properties = {\n             'addr_full': response.xpath('//*[@itemprop=\"streetAddress\"]/text()').extract_first(),\n             'city': response.xpath('//*[@itemprop=\"addressLocality\"]/text()').extract_first(),\n@@ -42,7 +47,7 @@\n \n         map_image_url = response.xpath('//img[@class=\"address-map\"]/@src').extract_first()\n         match = re.search(r\"center=(.*?),(.*?)&zoom\", map_image_url)\n-        properties['lat'] = float(match.group(1)),\n-        properties['lon'] = float(match.group(2)),\n+        properties['lat'] = float(match.group(1))\n+        properties['lon'] = float(match.group(2))\n \n         yield GeojsonPointItem(**properties)\n", "issue": "Spider planned_parenthood is broken\nDuring the global build at 2021-05-26-14-42-23, spider **planned_parenthood** failed with **598 features** and **598 errors**.\n\nHere's [the log](https://data.alltheplaces.xyz/runs/2021-05-26-14-42-23/logs/planned_parenthood.log) and [the output](https://data.alltheplaces.xyz/runs/2021-05-26-14-42-23/output/planned_parenthood.geojson) ([on a map](https://data.alltheplaces.xyz/map.html?show=https://data.alltheplaces.xyz/runs/2021-05-26-14-42-23/output/planned_parenthood.geojson))\n", "before_files": [{"content": "# -*- coding: utf-8 -*-\nimport scrapy\nimport re\n\nfrom locations.items import GeojsonPointItem\n\n\nclass PlannedParenthoodSpider(scrapy.Spider):\n    name = \"planned_parenthood\"\n    item_attributes = { 'brand': \"Planned Parenthood\" }\n    allowed_domains = [\"www.plannedparenthood.org\"]\n    start_urls = (\n        'https://www.plannedparenthood.org/health-center',\n    )\n\n    def parse(self, response):\n        state_urls = response.xpath('//ul[@class=\"quicklist-list\"]/li/a/@href').extract()\n        for path in state_urls:\n            yield scrapy.Request(\n                response.urljoin(path),\n                callback=self.parse_state,\n            )\n\n    def parse_state(self, response):\n        venue_urls = response.xpath('//ul[@class=\"quicklist-list\"]/li/p/a/@href').extract()\n        for path in venue_urls:\n            yield scrapy.Request(\n                response.urljoin(path),\n                callback=self.parse_venue,\n            )\n\n    def parse_venue(self, response):\n        properties = {\n            'addr_full': response.xpath('//*[@itemprop=\"streetAddress\"]/text()').extract_first(),\n            'city': response.xpath('//*[@itemprop=\"addressLocality\"]/text()').extract_first(),\n            'state': response.xpath('//*[@itemprop=\"addressRegion\"]/text()').extract_first(),\n            'postcode': response.xpath('//*[@itemprop=\"postalCode\"]/text()').extract_first(),\n            'phone': response.xpath('//a[@itemprop=\"telephone\"][@data-link]/text()').extract_first(),\n            'ref': response.url,\n            'website': response.url,\n        }\n\n        map_image_url = response.xpath('//img[@class=\"address-map\"]/@src').extract_first()\n        match = re.search(r\"center=(.*?),(.*?)&zoom\", map_image_url)\n        properties['lat'] = float(match.group(1)),\n        properties['lon'] = float(match.group(2)),\n\n        yield GeojsonPointItem(**properties)\n", "path": "locations/spiders/planned_parenthood.py"}], "after_files": [{"content": "# -*- coding: utf-8 -*-\nimport scrapy\nimport re\n\nfrom locations.items import GeojsonPointItem\n\n\nclass PlannedParenthoodSpider(scrapy.Spider):\n    name = \"planned_parenthood\"\n    item_attributes = { 'brand': \"Planned Parenthood\" }\n    allowed_domains = [\"www.plannedparenthood.org\"]\n    start_urls = (\n        'https://www.plannedparenthood.org/health-center',\n    )\n\n    def parse(self, response):\n        state_urls = response.xpath('//ul[@class=\"quicklist-list\"]/li/a/@href').extract()\n        for path in state_urls:\n            yield scrapy.Request(\n                response.urljoin(path),\n                callback=self.parse_state,\n            )\n\n    def parse_state(self, response):\n        venue_urls = response.xpath('//ul[@class=\"quicklist-list\"]/li/p/a/@href').extract()\n        for path in venue_urls:\n            yield scrapy.Request(\n                response.urljoin(path),\n                callback=self.parse_venue,\n                meta={'dont_redirect':True}\n            )\n\n    def parse_venue(self, response):\n        if response is None:\n            # Ignoring redirects\n            return\n\n        properties = {\n            'addr_full': response.xpath('//*[@itemprop=\"streetAddress\"]/text()').extract_first(),\n            'city': response.xpath('//*[@itemprop=\"addressLocality\"]/text()').extract_first(),\n            'state': response.xpath('//*[@itemprop=\"addressRegion\"]/text()').extract_first(),\n            'postcode': response.xpath('//*[@itemprop=\"postalCode\"]/text()').extract_first(),\n            'phone': response.xpath('//a[@itemprop=\"telephone\"][@data-link]/text()').extract_first(),\n            'ref': response.url,\n            'website': response.url,\n        }\n\n        map_image_url = response.xpath('//img[@class=\"address-map\"]/@src').extract_first()\n        match = re.search(r\"center=(.*?),(.*?)&zoom\", map_image_url)\n        properties['lat'] = float(match.group(1))\n        properties['lon'] = float(match.group(2))\n\n        yield GeojsonPointItem(**properties)\n", "path": "locations/spiders/planned_parenthood.py"}]}