Repository: alltheplaces/alltheplaces

Issue:
Micromania (FR) (shop/video_games) (314 stores)
### Brand name

Micromania

### Wikidata ID

Q3312221

### Store finder url(s)

https://www.micromania.fr/on/demandware.store/Sites-Micromania-Site/default/Stores-FindStoresLocator?radius=3000&postalCode=*


Discussion:

----
### Brand name

Micromania-Zing

video games and cultural products

### Wikidata ID

Q3312221
https://www.wikidata.org/wiki/Q3312221
https://www.wikidata.org/wiki/Special:EntityData/Q3312221.json

### Store finder url(s)

https://www.micromania.fr/magasins?mode=viewAll

Official Url(s): https://www.micromania.fr/
- [x] I have run the below and if anything in generated, added it.
- [x] I have manually checked for a storefinder
- [x] This is not a manufacturer listing outlets operating under their own brands / this will not create duplicates
`pipenv run scrapy sf --brand-wikidata=Q3312221 https://www.micromania.fr/`
```
```


Resolving patch:
diff --git a/locations/spiders/micromania_fr.py b/locations/spiders/micromania_fr.py
new file mode 100644
--- /dev/null
+++ b/locations/spiders/micromania_fr.py
@@ -0,0 +1,57 @@
+import json
+from html import unescape
+
+from scrapy import Request, Selector
+from scrapy.http import JsonRequest
+
+from locations.categories import Categories
+from locations.hours import DAYS_FR, OpeningHours
+from locations.structured_data_spider import StructuredDataSpider
+
+
+class MicromaniaFRSpider(StructuredDataSpider):
+    name = "micromania_fr"
+    item_attributes = {"brand": "Micromania", "brand_wikidata": "Q3312221", "extras": Categories.SHOP_VIDEO_GAMES.value}
+    allowed_domains = ["www.micromania.fr"]
+    start_urls = [
+        "https://www.micromania.fr/on/demandware.store/Sites-Micromania-Site/default/Stores-FindStoresLocator?radius=3000&postalCode=*"
+    ]
+
+    def start_requests(self):
+        for url in self.start_urls:
+            yield JsonRequest(url=url, callback=self.parse_store_list)
+
+    def parse_store_list(self, response):
+        locations = json.loads(response.json()["locations"])
+        for location in locations:
+            html_blob = Selector(text=location["infoWindowHtml"])
+            store_page = html_blob.xpath('//a[contains(@class, "info-window__magazine-link")]/@href').get()
+            yield Request(url=store_page, callback=self.parse_sd)
+
+    def post_process_item(self, item, response, ld_data):
+        item["ref"] = response.url.split("?storeid=", 1)[1]
+        item["street_address"] = ", ".join(
+            filter(
+                None,
+                map(
+                    str.strip,
+                    response.xpath(
+                        '//p[@itemprop="address"]//text()/parent::*[@itemprop="streetAddress" or @itemprop="address"]/text()'
+                    ).getall(),
+                ),
+            )
+        )
+        item.pop("facebook", None)
+        item.pop("twitter", None)
+
+        hours_json_string = unescape(" ".join(response.xpath('//span[@itemprop="openingHours"]/text()').getall()))
+        hours_json = json.loads(hours_json_string)
+        item["opening_hours"] = OpeningHours()
+        for day_hours in hours_json.values():
+            if day_hours["ouverture"] == day_hours["fermeture"]:
+                continue
+            item["opening_hours"].add_range(
+                DAYS_FR[day_hours["name"]], day_hours["ouverture"], day_hours["fermeture"], "%H:%M:%S"
+            )
+
+        yield item


Test patch: