Repository: alltheplaces/alltheplaces

Issue:
Spider teavana is broken
During the global build at 2021-05-26-14-42-23, spider **teavana** failed with **0 features** and **2 errors**.

Here's [the log](https://data.alltheplaces.xyz/runs/2021-05-26-14-42-23/logs/teavana.log) and [the output](https://data.alltheplaces.xyz/runs/2021-05-26-14-42-23/output/teavana.geojson) ([on a map](https://data.alltheplaces.xyz/map.html?show=https://data.alltheplaces.xyz/runs/2021-05-26-14-42-23/output/teavana.geojson))


Discussion:
During the global build at 2021-06-30-14-42-26, spider **teavana** failed with **0 features** and **2 errors**.

Here's [the log](https://data.alltheplaces.xyz/runs/2021-06-30-14-42-26/logs/teavana.txt) and [the output](https://data.alltheplaces.xyz/runs/2021-06-30-14-42-26/output/teavana.geojson) ([on a map](https://data.alltheplaces.xyz/map.html?show=https://data.alltheplaces.xyz/runs/2021-06-30-14-42-26/output/teavana.geojson))
During the global build at 2021-07-14-14-42-22, spider **teavana** failed with **0 features** and **2 errors**.

Here's [the log](https://data.alltheplaces.xyz/runs/2021-07-14-14-42-22/logs/teavana.txt) and [the output](https://data.alltheplaces.xyz/runs/2021-07-14-14-42-22/output/teavana.geojson) ([on a map](https://data.alltheplaces.xyz/map.html?show=https://data.alltheplaces.xyz/runs/2021-07-14-14-42-22/output/teavana.geojson))
During the global build at 2021-07-21-14-42-39, spider **teavana** failed with **0 features** and **2 errors**.

Here's [the log](https://data.alltheplaces.xyz/runs/2021-07-21-14-42-39/logs/teavana.txt) and [the output](https://data.alltheplaces.xyz/runs/2021-07-21-14-42-39/output/teavana.geojson) ([on a map](https://data.alltheplaces.xyz/map.html?show=https://data.alltheplaces.xyz/runs/2021-07-21-14-42-39/output/teavana.geojson))

Resolving patch:
diff --git a/locations/spiders/teavana.py b/locations/spiders/teavana.py
deleted file mode 100644
--- a/locations/spiders/teavana.py
+++ /dev/null
@@ -1,89 +0,0 @@
-import scrapy
-import re
-from locations.items import GeojsonPointItem
-
-
-class ExpressSpider(scrapy.Spider):
-
-    name = "teavana"
-    item_attributes = {"brand": "Teavana"}
-    allowed_domains = ["locations.teavana.com"]
-    download_delay = 0.5
-    start_urls = ("https://locations.teavana.com/",)
-
-    def parse_stores(self, response):
-        ref = re.findall(r"[^(\/)]+$", response.url)
-        if len(ref) > 0:
-            ref = ref[0].split(".")[0]
-        properties = {
-            "addr_full": " ".join(
-                response.xpath(
-                    '//span[@itemprop="streetAddress"]/span/text()'
-                ).extract()
-            ),
-            "phone": response.xpath(
-                'normalize-space(//span[@itemprop="telephone"]/text())'
-            ).extract_first(),
-            "city": response.xpath(
-                'normalize-space(//span[@itemprop="addressLocality"]/text())'
-            ).extract_first(),
-            "state": response.xpath(
-                'normalize-space(//abbr[@itemprop="addressRegion"]/text())'
-            ).extract_first(),
-            "postcode": response.xpath(
-                'normalize-space(//span[@itemprop="postalCode"]/text())'
-            ).extract_first(),
-            "ref": ref,
-            "website": response.url,
-            "lat": float(
-                response.xpath(
-                    'normalize-space(//meta[@itemprop="latitude"]/@content)'
-                ).extract_first()
-            ),
-            "lon": float(
-                response.xpath(
-                    'normalize-space(//meta[@itemprop="longitude"]/@content)'
-                ).extract_first()
-            ),
-        }
-        hours = response.xpath('//div[@itemprop="openingHours"]/@content').extract()
-        if hours != []:
-            hours = "; ".join(hours)
-            properties["opening_hours"] = hours
-        yield GeojsonPointItem(**properties)
-
-    def parse_city_stores(self, response):
-        stores = response.xpath(
-            '//h3[@class="Teaser-title Link Link--teaser Heading--h5"]/a/@href'
-        ).extract()
-        for store in stores:
-            yield scrapy.Request(response.urljoin(store), callback=self.parse_stores)
-
-    def parse_state(self, response):
-        urls = response.xpath(
-            '//div[@class="c-directory-list-content-wrapper"]/ul/li/a/@href'
-        ).extract()
-        for path in urls:
-            pattern = re.compile(r"..\/[a-z]{2}\/[a-z]{2}\/[^()]+\/[^()]+.html$")
-            if pattern.match(path.strip()):
-                yield scrapy.Request(response.urljoin(path), callback=self.parse_stores)
-            else:
-                yield scrapy.Request(
-                    response.urljoin(path), callback=self.parse_city_stores
-                )
-
-    def parse(self, response):
-        urls = response.xpath(
-            '//div[@class="c-directory-list-content-wrapper"]/ul/li/a/@href'
-        ).extract()
-        for path in urls:
-            pattern = re.compile(r"^[a-z]{2}\/[a-z]{2}.html$")
-            pattern1 = re.compile(r"^[a-z]{2}\/[a-z]{2}\/[^()]+\/[^()]+.html$")
-            if pattern.match(path.strip()):
-                yield scrapy.Request(response.urljoin(path), callback=self.parse_state)
-            elif pattern1.match(path.strip()):
-                yield scrapy.Request(response.urljoin(path), callback=self.parse_stores)
-            else:
-                yield scrapy.Request(
-                    response.urljoin(path), callback=self.parse_city_stores
-                )


Test patch: