prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  Spider anthonys_restaurants is broken
  During the global build at 2021-06-16-14-42-20, spider **anthonys_restaurants** failed with **0 features** and **0 errors**.
  
  Here's [the log](https://data.alltheplaces.xyz/runs/2021-06-16-14-42-20/logs/anthonys_restaurants.txt) and [the output](https://data.alltheplaces.xyz/runs/2021-06-16-14-42-20/output/anthonys_restaurants.geojson) ([on a map](https://data.alltheplaces.xyz/map.html?show=https://data.alltheplaces.xyz/runs/2021-06-16-14-42-20/output/anthonys_restaurants.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/anthonys_restaurants.py`
  Content:
  ```
  1 # -*- coding: utf-8 -*-
  2 import scrapy
  3 from locations.items import GeojsonPointItem
  4 
  5 
  6 class AnthonysRestaurantsSpiders(scrapy.Spider):
  7     name = "anthonys_restaurants"
  8     item_attributes = { 'brand': "Anthony's" }
  9     allowed_domains = ["www.anthonys.com"]
  10     start_urls = (
  11         'https://www.anthonys.com/restaurants/search/47.6062095/-122.3320708/2000',
  12     )
  13 
  14     def parse(self, response):
  15         for match in response.xpath("//markers/marker"):
  16             fullAddress=match.xpath('.//@address').extract_first().replace('<br />', ',')
  17 
  18             # Accounts for cases with second address line
  19             if(len(fullAddress.split(",")) == 4):
  20                 cityString = fullAddress.split(",")[2].strip()
  21                 stateString = fullAddress.split(",")[3].strip().split(" ")[0].strip()
  22                 postString = fullAddress.split(",")[3].strip().split(" ")[1].strip()
  23                 addrLineOne = fullAddress.split(",")[0].strip()
  24                 addrLineTwo = fullAddress.split(",")[1].strip()
  25                 addrString = addrLineOne + ", " + addrLineTwo
  26             else:
  27                 cityString = fullAddress.split(",")[1].strip()
  28                 stateString = fullAddress.split(",")[2].strip().split(" ")[0].strip()
  29                 postString = fullAddress.split(",")[2].strip().split(" ")[1].strip()
  30                 addrString = fullAddress.split(",")[0]
  31 
  32             yield GeojsonPointItem(
  33                 ref=match.xpath('.//@title').extract_first().strip(),
  34                 lat=match.xpath('.//@lat').extract_first().strip(),
  35                 lon=match.xpath('.//@lng').extract_first().strip(),
  36                 addr_full=addrString,
  37                 city=cityString,
  38                 state=stateString,
  39                 postcode=postString,
  40                 phone=match.xpath('.//@phone').extract_first().replace(" ", ""),
  41             )
  42
  ```
  --- 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/anthonys_restaurants.py b/locations/spiders/anthonys_restaurants.py
  --- a/locations/spiders/anthonys_restaurants.py
  +++ b/locations/spiders/anthonys_restaurants.py
  @@ -1,41 +1,49 @@
   # -*- coding: utf-8 -*-
  +import json
  +import re
  +
   import scrapy
  +
   from locations.items import GeojsonPointItem
   
   
   class AnthonysRestaurantsSpiders(scrapy.Spider):
       name = "anthonys_restaurants"
  -    item_attributes = { 'brand': "Anthony's" }
  +    item_attributes = {"brand": "Anthony's"}
       allowed_domains = ["www.anthonys.com"]
  -    start_urls = (
  -        'https://www.anthonys.com/restaurants/search/47.6062095/-122.3320708/2000',
  -    )
  +    start_urls = ("https://www.anthonys.com/restaurants/",)
   
       def parse(self, response):
  -        for match in response.xpath("//markers/marker"):
  -            fullAddress=match.xpath('.//@address').extract_first().replace('<br />', ',')
  -
  -            # Accounts for cases with second address line
  -            if(len(fullAddress.split(",")) == 4):
  -                cityString = fullAddress.split(",")[2].strip()
  -                stateString = fullAddress.split(",")[3].strip().split(" ")[0].strip()
  -                postString = fullAddress.split(",")[3].strip().split(" ")[1].strip()
  -                addrLineOne = fullAddress.split(",")[0].strip()
  -                addrLineTwo = fullAddress.split(",")[1].strip()
  -                addrString = addrLineOne + ", " + addrLineTwo
  -            else:
  -                cityString = fullAddress.split(",")[1].strip()
  -                stateString = fullAddress.split(",")[2].strip().split(" ")[0].strip()
  -                postString = fullAddress.split(",")[2].strip().split(" ")[1].strip()
  -                addrString = fullAddress.split(",")[0]
  -
  -            yield GeojsonPointItem(
  -                ref=match.xpath('.//@title').extract_first().strip(),
  -                lat=match.xpath('.//@lat').extract_first().strip(),
  -                lon=match.xpath('.//@lng').extract_first().strip(),
  -                addr_full=addrString,
  -                city=cityString,
  -                state=stateString,
  -                postcode=postString,
  -                phone=match.xpath('.//@phone').extract_first().replace(" ", ""),
  -            )
  +        script = response.css("#acf-block-locations-map-script-js-extra::text").get()
  +        j = json.loads(script[script.find("{") : 1 + script.rfind("}")])
  +        for row in j["restaurants"]:
  +            meta = {"json": row}
  +            yield scrapy.Request(row["link"], meta=meta, callback=self.parse_location)
  +
  +    def parse_location(self, response):
  +        json_data = response.meta["json"]
  +        address = json_data["address"]
  +        # decode entities
  +        name = scrapy.Selector(text=json_data["name"]).xpath("//text()").get()
  +
  +        # These are weird enough that there's no hope of parsing them, but
  +        # clean the text up
  +        hours = response.xpath('//strong[text()="Hours:"]/../text()').extract()
  +        hours = ';'.join(s.strip().replace('\xa0', ' ') for s in hours)
  +
  +        properties = {
  +            "ref": re.search(r"postid-(\d+)", response.css("body").attrib["class"])[1],
  +            "lat": address["latitude"],
  +            "lon": address["longitude"],
  +            "addr_full": address["address"],
  +            "city": address["city"],
  +            "state": address["state"],
  +            "postcode": address["zip_code"],
  +            "name": name,
  +            "website": response.url,
  +            "phone": (
  +                response.xpath("//*[starts-with(@href, 'tel:')]/@href").get() or ""
  +            )[4:],
  +            "opening_hours": hours,
  +        }
  +        return GeojsonPointItem(**properties)
  
verification_info: {"golden_diff": "diff --git a/locations/spiders/anthonys_restaurants.py b/locations/spiders/anthonys_restaurants.py\n--- a/locations/spiders/anthonys_restaurants.py\n+++ b/locations/spiders/anthonys_restaurants.py\n@@ -1,41 +1,49 @@\n # -*- coding: utf-8 -*-\n+import json\n+import re\n+\n import scrapy\n+\n from locations.items import GeojsonPointItem\n \n \n class AnthonysRestaurantsSpiders(scrapy.Spider):\n     name = \"anthonys_restaurants\"\n-    item_attributes = { 'brand': \"Anthony's\" }\n+    item_attributes = {\"brand\": \"Anthony's\"}\n     allowed_domains = [\"www.anthonys.com\"]\n-    start_urls = (\n-        'https://www.anthonys.com/restaurants/search/47.6062095/-122.3320708/2000',\n-    )\n+    start_urls = (\"https://www.anthonys.com/restaurants/\",)\n \n     def parse(self, response):\n-        for match in response.xpath(\"//markers/marker\"):\n-            fullAddress=match.xpath('.//@address').extract_first().replace('<br />', ',')\n-\n-            # Accounts for cases with second address line\n-            if(len(fullAddress.split(\",\")) == 4):\n-                cityString = fullAddress.split(\",\")[2].strip()\n-                stateString = fullAddress.split(\",\")[3].strip().split(\" \")[0].strip()\n-                postString = fullAddress.split(\",\")[3].strip().split(\" \")[1].strip()\n-                addrLineOne = fullAddress.split(\",\")[0].strip()\n-                addrLineTwo = fullAddress.split(\",\")[1].strip()\n-                addrString = addrLineOne + \", \" + addrLineTwo\n-            else:\n-                cityString = fullAddress.split(\",\")[1].strip()\n-                stateString = fullAddress.split(\",\")[2].strip().split(\" \")[0].strip()\n-                postString = fullAddress.split(\",\")[2].strip().split(\" \")[1].strip()\n-                addrString = fullAddress.split(\",\")[0]\n-\n-            yield GeojsonPointItem(\n-                ref=match.xpath('.//@title').extract_first().strip(),\n-                lat=match.xpath('.//@lat').extract_first().strip(),\n-                lon=match.xpath('.//@lng').extract_first().strip(),\n-                addr_full=addrString,\n-                city=cityString,\n-                state=stateString,\n-                postcode=postString,\n-                phone=match.xpath('.//@phone').extract_first().replace(\" \", \"\"),\n-            )\n+        script = response.css(\"#acf-block-locations-map-script-js-extra::text\").get()\n+        j = json.loads(script[script.find(\"{\") : 1 + script.rfind(\"}\")])\n+        for row in j[\"restaurants\"]:\n+            meta = {\"json\": row}\n+            yield scrapy.Request(row[\"link\"], meta=meta, callback=self.parse_location)\n+\n+    def parse_location(self, response):\n+        json_data = response.meta[\"json\"]\n+        address = json_data[\"address\"]\n+        # decode entities\n+        name = scrapy.Selector(text=json_data[\"name\"]).xpath(\"//text()\").get()\n+\n+        # These are weird enough that there's no hope of parsing them, but\n+        # clean the text up\n+        hours = response.xpath('//strong[text()=\"Hours:\"]/../text()').extract()\n+        hours = ';'.join(s.strip().replace('\\xa0', ' ') for s in hours)\n+\n+        properties = {\n+            \"ref\": re.search(r\"postid-(\\d+)\", response.css(\"body\").attrib[\"class\"])[1],\n+            \"lat\": address[\"latitude\"],\n+            \"lon\": address[\"longitude\"],\n+            \"addr_full\": address[\"address\"],\n+            \"city\": address[\"city\"],\n+            \"state\": address[\"state\"],\n+            \"postcode\": address[\"zip_code\"],\n+            \"name\": name,\n+            \"website\": response.url,\n+            \"phone\": (\n+                response.xpath(\"//*[starts-with(@href, 'tel:')]/@href\").get() or \"\"\n+            )[4:],\n+            \"opening_hours\": hours,\n+        }\n+        return GeojsonPointItem(**properties)\n", "issue": "Spider anthonys_restaurants is broken\nDuring the global build at 2021-06-16-14-42-20, spider **anthonys_restaurants** failed with **0 features** and **0 errors**.\n\nHere's [the log](https://data.alltheplaces.xyz/runs/2021-06-16-14-42-20/logs/anthonys_restaurants.txt) and [the output](https://data.alltheplaces.xyz/runs/2021-06-16-14-42-20/output/anthonys_restaurants.geojson) ([on a map](https://data.alltheplaces.xyz/map.html?show=https://data.alltheplaces.xyz/runs/2021-06-16-14-42-20/output/anthonys_restaurants.geojson))\n", "before_files": [{"content": "# -*- coding: utf-8 -*-\nimport scrapy\nfrom locations.items import GeojsonPointItem\n\n\nclass AnthonysRestaurantsSpiders(scrapy.Spider):\n    name = \"anthonys_restaurants\"\n    item_attributes = { 'brand': \"Anthony's\" }\n    allowed_domains = [\"www.anthonys.com\"]\n    start_urls = (\n        'https://www.anthonys.com/restaurants/search/47.6062095/-122.3320708/2000',\n    )\n\n    def parse(self, response):\n        for match in response.xpath(\"//markers/marker\"):\n            fullAddress=match.xpath('.//@address').extract_first().replace('<br />', ',')\n\n            # Accounts for cases with second address line\n            if(len(fullAddress.split(\",\")) == 4):\n                cityString = fullAddress.split(\",\")[2].strip()\n                stateString = fullAddress.split(\",\")[3].strip().split(\" \")[0].strip()\n                postString = fullAddress.split(\",\")[3].strip().split(\" \")[1].strip()\n                addrLineOne = fullAddress.split(\",\")[0].strip()\n                addrLineTwo = fullAddress.split(\",\")[1].strip()\n                addrString = addrLineOne + \", \" + addrLineTwo\n            else:\n                cityString = fullAddress.split(\",\")[1].strip()\n                stateString = fullAddress.split(\",\")[2].strip().split(\" \")[0].strip()\n                postString = fullAddress.split(\",\")[2].strip().split(\" \")[1].strip()\n                addrString = fullAddress.split(\",\")[0]\n\n            yield GeojsonPointItem(\n                ref=match.xpath('.//@title').extract_first().strip(),\n                lat=match.xpath('.//@lat').extract_first().strip(),\n                lon=match.xpath('.//@lng').extract_first().strip(),\n                addr_full=addrString,\n                city=cityString,\n                state=stateString,\n                postcode=postString,\n                phone=match.xpath('.//@phone').extract_first().replace(\" \", \"\"),\n            )\n", "path": "locations/spiders/anthonys_restaurants.py"}], "after_files": [{"content": "# -*- coding: utf-8 -*-\nimport json\nimport re\n\nimport scrapy\n\nfrom locations.items import GeojsonPointItem\n\n\nclass AnthonysRestaurantsSpiders(scrapy.Spider):\n    name = \"anthonys_restaurants\"\n    item_attributes = {\"brand\": \"Anthony's\"}\n    allowed_domains = [\"www.anthonys.com\"]\n    start_urls = (\"https://www.anthonys.com/restaurants/\",)\n\n    def parse(self, response):\n        script = response.css(\"#acf-block-locations-map-script-js-extra::text\").get()\n        j = json.loads(script[script.find(\"{\") : 1 + script.rfind(\"}\")])\n        for row in j[\"restaurants\"]:\n            meta = {\"json\": row}\n            yield scrapy.Request(row[\"link\"], meta=meta, callback=self.parse_location)\n\n    def parse_location(self, response):\n        json_data = response.meta[\"json\"]\n        address = json_data[\"address\"]\n        # decode entities\n        name = scrapy.Selector(text=json_data[\"name\"]).xpath(\"//text()\").get()\n\n        # These are weird enough that there's no hope of parsing them, but\n        # clean the text up\n        hours = response.xpath('//strong[text()=\"Hours:\"]/../text()').extract()\n        hours = ';'.join(s.strip().replace('\\xa0', ' ') for s in hours)\n\n        properties = {\n            \"ref\": re.search(r\"postid-(\\d+)\", response.css(\"body\").attrib[\"class\"])[1],\n            \"lat\": address[\"latitude\"],\n            \"lon\": address[\"longitude\"],\n            \"addr_full\": address[\"address\"],\n            \"city\": address[\"city\"],\n            \"state\": address[\"state\"],\n            \"postcode\": address[\"zip_code\"],\n            \"name\": name,\n            \"website\": response.url,\n            \"phone\": (\n                response.xpath(\"//*[starts-with(@href, 'tel:')]/@href\").get() or \"\"\n            )[4:],\n            \"opening_hours\": hours,\n        }\n        return GeojsonPointItem(**properties)\n", "path": "locations/spiders/anthonys_restaurants.py"}]}