warn-scraper 1.2.156.dev0__py3-none-any.whl → 1.2.158.dev0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- warn/scrapers/al.py +34 -39
- {warn_scraper-1.2.156.dev0.dist-info → warn_scraper-1.2.158.dev0.dist-info}/METADATA +1 -1
- {warn_scraper-1.2.156.dev0.dist-info → warn_scraper-1.2.158.dev0.dist-info}/RECORD +9 -7
- warn_scraper-1.2.158.dev0.dist-info/scm_file_list.json +137 -0
- warn_scraper-1.2.158.dev0.dist-info/scm_version.json +8 -0
- {warn_scraper-1.2.156.dev0.dist-info → warn_scraper-1.2.158.dev0.dist-info}/WHEEL +0 -0
- {warn_scraper-1.2.156.dev0.dist-info → warn_scraper-1.2.158.dev0.dist-info}/entry_points.txt +0 -0
- {warn_scraper-1.2.156.dev0.dist-info → warn_scraper-1.2.158.dev0.dist-info}/licenses/LICENSE +0 -0
- {warn_scraper-1.2.156.dev0.dist-info → warn_scraper-1.2.158.dev0.dist-info}/top_level.txt +0 -0
warn/scrapers/al.py
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
|
+
import csv
|
|
1
2
|
import logging
|
|
2
|
-
import
|
|
3
|
+
from io import StringIO
|
|
3
4
|
from pathlib import Path
|
|
4
5
|
|
|
5
|
-
from bs4 import BeautifulSoup
|
|
6
|
-
|
|
7
6
|
from .. import utils
|
|
7
|
+
from ..cache import Cache
|
|
8
8
|
|
|
9
|
-
__authors__ = ["zstumgoren", "Dilcia19"]
|
|
9
|
+
__authors__ = ["zstumgoren", "Dilcia19", "stucka"]
|
|
10
10
|
__tags__ = [
|
|
11
|
-
"
|
|
11
|
+
"csv",
|
|
12
12
|
]
|
|
13
13
|
__source__ = {
|
|
14
14
|
"name": "Alabama Department of Commerce",
|
|
@@ -31,45 +31,40 @@ def scrape(
|
|
|
31
31
|
|
|
32
32
|
Returns: the Path where the file is written
|
|
33
33
|
"""
|
|
34
|
+
cache = Cache()
|
|
34
35
|
output_csv = data_dir / "al.csv"
|
|
36
|
+
|
|
35
37
|
# page = utils.get_url("https://www.madeinalabama.com/warn-list/")
|
|
36
38
|
# URL change in June 2026, maybe led to a HTTP 415 error
|
|
37
|
-
page = utils.get_url("https://workforce.alabama.gov/warn-list/")
|
|
38
|
-
|
|
39
|
-
#
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
raw_header = table_rows.pop(0)
|
|
46
|
-
header_row = _extract_fields_from_row(raw_header, "th")
|
|
47
|
-
output_rows = [header_row]
|
|
48
|
-
# Process remaining rows
|
|
49
|
-
discarded_rows = []
|
|
50
|
-
for table_row in table_rows:
|
|
51
|
-
# Discard bogus data lines (see last lines of source data)
|
|
52
|
-
# based on check of first field ("Closing or Layoff")
|
|
53
|
-
data = _extract_fields_from_row(table_row, "td")
|
|
54
|
-
layoff_type = data[0]
|
|
55
|
-
if re.match(r"(clos|lay)", layoff_type, re.I):
|
|
56
|
-
output_rows.append(data)
|
|
57
|
-
else:
|
|
58
|
-
discarded_rows.append(data)
|
|
59
|
-
if discarded_rows:
|
|
60
|
-
logger.warn(f"Warning: Discarded {len(discarded_rows)} dirty data row(s)")
|
|
61
|
-
utils.write_rows_to_csv(output_csv, output_rows)
|
|
62
|
-
return output_csv
|
|
39
|
+
# page = utils.get_url("https://workforce.alabama.gov/warn-list/")
|
|
40
|
+
# Later in June 2026, they're detecting the automation and blocking us.
|
|
41
|
+
# But say they won't for the CSV download which, OK.
|
|
42
|
+
# No headers on the CSV, which they'll probably realize ... sometime.
|
|
43
|
+
|
|
44
|
+
targeturl = "https://workforce.alabama.gov/documents/warn-list/"
|
|
45
|
+
page = utils.get_url(targeturl).text
|
|
46
|
+
cache.write("al/rawcsv.csv", page)
|
|
63
47
|
|
|
48
|
+
headers = [
|
|
49
|
+
"_id1",
|
|
50
|
+
"action_type",
|
|
51
|
+
"date_notice",
|
|
52
|
+
"date_action",
|
|
53
|
+
"company",
|
|
54
|
+
"location",
|
|
55
|
+
"affected",
|
|
56
|
+
"_id2",
|
|
57
|
+
]
|
|
64
58
|
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
59
|
+
fileholder = StringIO(page)
|
|
60
|
+
|
|
61
|
+
reader = list(csv.DictReader(fileholder, fieldnames=headers))
|
|
62
|
+
|
|
63
|
+
utils.write_disparate_dict_rows_to_csv(
|
|
64
|
+
output_csv, reader, mode="w", prefixes=["_id"]
|
|
65
|
+
)
|
|
66
|
+
|
|
67
|
+
return output_csv
|
|
73
68
|
|
|
74
69
|
|
|
75
70
|
if __name__ == "__main__":
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: warn-scraper
|
|
3
|
-
Version: 1.2.
|
|
3
|
+
Version: 1.2.158.dev0
|
|
4
4
|
Summary: Command-line interface for downloading WARN Act notices of qualified plant closings and mass layoffs from state government websites
|
|
5
5
|
Author-email: Big Local News <biglocalnews@stanford.edu>
|
|
6
6
|
License-Expression: Apache-2.0
|
|
@@ -13,7 +13,7 @@ warn/platforms/job_center/urls.py,sha256=IWhpuzN_xcNdHh23GbZPGvuHCsMcmb03qx3pRn1
|
|
|
13
13
|
warn/platforms/job_center/utils.py,sha256=HdUKgKirmpPP7e4Cu_ZyB3zPVS_p-_ylo-lXFhxK2QM,5696
|
|
14
14
|
warn/scrapers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
15
15
|
warn/scrapers/ak.py,sha256=h7BYMTV0whwWAPhbzVDVKMMoVCFphKly70aiTHabPq4,1847
|
|
16
|
-
warn/scrapers/al.py,sha256=
|
|
16
|
+
warn/scrapers/al.py,sha256=3_OtgUp4K6OL6H63SdtLQWE998r8PQpTNOv6PuiJEEc,1888
|
|
17
17
|
warn/scrapers/az.py,sha256=elGbue01Gjf_DQ66Wy9qqGIOJsiY-KIKJOVeft8pCXg,1447
|
|
18
18
|
warn/scrapers/ca.py,sha256=VQOfjHXPCc-jYwh-EPGVVfnzvXB7pdmCt2uJ6QnMPRM,8600
|
|
19
19
|
warn/scrapers/co.py,sha256=83OdikIrWGxt22mlI-_zLSNqJg1NO5C2Xjm3FF6DPYY,18252
|
|
@@ -54,9 +54,11 @@ warn/scrapers/va.py,sha256=7Nle7qL0VNPiE653XyaP9HQqSfuJFDRr2kEkjOqLvFM,11269
|
|
|
54
54
|
warn/scrapers/vt.py,sha256=d-bo4WK2hkrk4BhCCmLpEovcoZltlvdIUB6O0uaMx5A,1186
|
|
55
55
|
warn/scrapers/wa.py,sha256=UXdVtHZo_a-XfoiyOooTRfTb9W3PErSZdKca6SRORgs,4282
|
|
56
56
|
warn/scrapers/wi.py,sha256=ClEzXkwZbop0W4fkQgsb5oHAPUrb4luUPGV-jOKwkcg,4855
|
|
57
|
-
warn_scraper-1.2.
|
|
58
|
-
warn_scraper-1.2.
|
|
59
|
-
warn_scraper-1.2.
|
|
60
|
-
warn_scraper-1.2.
|
|
61
|
-
warn_scraper-1.2.
|
|
62
|
-
warn_scraper-1.2.
|
|
57
|
+
warn_scraper-1.2.158.dev0.dist-info/licenses/LICENSE,sha256=ZV-QHyqPwyMuwuj0lI05JeSjV1NyzVEk8Yeu7FPtYS0,585
|
|
58
|
+
warn_scraper-1.2.158.dev0.dist-info/METADATA,sha256=eEAoxrMSjuAIXEEF7mpOOan9f74w4CacJtNiWOxPM6E,1780
|
|
59
|
+
warn_scraper-1.2.158.dev0.dist-info/WHEEL,sha256=aeYiig01lYGDzBgS8HxWXOg3uV61G9ijOsup-k9o1sk,91
|
|
60
|
+
warn_scraper-1.2.158.dev0.dist-info/entry_points.txt,sha256=poh_oSweObGlBSs1_2qZmnTodlOYD0KfO7-h7W2UQIw,47
|
|
61
|
+
warn_scraper-1.2.158.dev0.dist-info/scm_file_list.json,sha256=SBROd7oEfcspIMl6v7yfGzQd2rkWxybkiIXopuTQVL0,4120
|
|
62
|
+
warn_scraper-1.2.158.dev0.dist-info/scm_version.json,sha256=XFb9EYQ2iJW5cLXZGITnEVHhw7wZNgPoYMAsYnRCNbU,161
|
|
63
|
+
warn_scraper-1.2.158.dev0.dist-info/top_level.txt,sha256=dZfms6N3kqVXufiPOo7YqOrAcUtYfNH_oyGvYUk9FB4,5
|
|
64
|
+
warn_scraper-1.2.158.dev0.dist-info/RECORD,,
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
{
|
|
2
|
+
"files": [
|
|
3
|
+
".pre-commit-config.yaml",
|
|
4
|
+
"README.md",
|
|
5
|
+
"Makefile",
|
|
6
|
+
"setup.cfg",
|
|
7
|
+
"LICENSE",
|
|
8
|
+
"setup.py",
|
|
9
|
+
"pyproject.toml",
|
|
10
|
+
"Pipfile.lock",
|
|
11
|
+
"MANIFEST.in",
|
|
12
|
+
"Pipfile",
|
|
13
|
+
".gitignore",
|
|
14
|
+
".devcontainer/devcontainer.json",
|
|
15
|
+
"docs/reference.rst",
|
|
16
|
+
"docs/releasing.md",
|
|
17
|
+
"docs/Makefile",
|
|
18
|
+
"docs/sources.md",
|
|
19
|
+
"docs/contributing.rst",
|
|
20
|
+
"docs/index.rst",
|
|
21
|
+
"docs/requirements.txt",
|
|
22
|
+
"docs/make.bat",
|
|
23
|
+
"docs/usage.md",
|
|
24
|
+
"docs/conf.py",
|
|
25
|
+
"docs/scrapers/az.md",
|
|
26
|
+
"docs/scrapers/de.md",
|
|
27
|
+
"docs/scrapers/or.md",
|
|
28
|
+
"docs/scrapers/tx.md",
|
|
29
|
+
"docs/scrapers/sc.md",
|
|
30
|
+
"docs/scrapers/vt.md",
|
|
31
|
+
"docs/scrapers/job_center.md",
|
|
32
|
+
"docs/scrapers/dc.md",
|
|
33
|
+
"docs/scrapers/ut.md",
|
|
34
|
+
"docs/scrapers/mo.md",
|
|
35
|
+
"docs/scrapers/al.md",
|
|
36
|
+
"docs/scrapers/me.md",
|
|
37
|
+
"docs/scrapers/ks.md",
|
|
38
|
+
"docs/scrapers/in.md",
|
|
39
|
+
"docs/scrapers/ok.md",
|
|
40
|
+
"docs/scrapers/co.md",
|
|
41
|
+
"docs/scrapers/ia.md",
|
|
42
|
+
"docs/scrapers/va.md",
|
|
43
|
+
"docs/scrapers/md.md",
|
|
44
|
+
"docs/scrapers/ny.md",
|
|
45
|
+
"docs/scrapers/wi.md",
|
|
46
|
+
"docs/scrapers/ca.md",
|
|
47
|
+
"docs/_static/releasing-changelog-entered.png",
|
|
48
|
+
"docs/_static/releasing-publish-button.png",
|
|
49
|
+
"docs/_static/releasing-actions-start.png",
|
|
50
|
+
"docs/_static/gao-03-1003.pdf",
|
|
51
|
+
"docs/_static/releasing-tag-button.png",
|
|
52
|
+
"docs/_static/releasing-name-tag.png",
|
|
53
|
+
"docs/_static/releasing-draft-button.png",
|
|
54
|
+
"docs/_static/releasing-releases-button.png",
|
|
55
|
+
"docs/_static/R42693.pdf",
|
|
56
|
+
"docs/_static/releasing-actions-finished.png",
|
|
57
|
+
"docs/_static/releasing-pypi.png",
|
|
58
|
+
"docs/_static/releasing-name-release.png",
|
|
59
|
+
"docs/_static/releasing-release-published.png",
|
|
60
|
+
"docs/_static/releasing-changelog-button.png",
|
|
61
|
+
"docs/_templates/sources.md.tmpl",
|
|
62
|
+
"warn/__init__.py",
|
|
63
|
+
"warn/utils.py",
|
|
64
|
+
"warn/runner.py",
|
|
65
|
+
"warn/cache.py",
|
|
66
|
+
"warn/cli.py",
|
|
67
|
+
"warn/scrapers/az.py",
|
|
68
|
+
"warn/scrapers/la.py",
|
|
69
|
+
"warn/scrapers/tx.py",
|
|
70
|
+
"warn/scrapers/wa.py",
|
|
71
|
+
"warn/scrapers/wi.py",
|
|
72
|
+
"warn/scrapers/ga.py",
|
|
73
|
+
"warn/scrapers/co.py",
|
|
74
|
+
"warn/scrapers/de.py",
|
|
75
|
+
"warn/scrapers/__init__.py",
|
|
76
|
+
"warn/scrapers/ia.py",
|
|
77
|
+
"warn/scrapers/al.py",
|
|
78
|
+
"warn/scrapers/fl.py",
|
|
79
|
+
"warn/scrapers/nj.py",
|
|
80
|
+
"warn/scrapers/mi.py",
|
|
81
|
+
"warn/scrapers/vt.py",
|
|
82
|
+
"warn/scrapers/mt.py",
|
|
83
|
+
"warn/scrapers/md.py",
|
|
84
|
+
"warn/scrapers/sc.py",
|
|
85
|
+
"warn/scrapers/ut.py",
|
|
86
|
+
"warn/scrapers/il.py",
|
|
87
|
+
"warn/scrapers/ky.py",
|
|
88
|
+
"warn/scrapers/or.py",
|
|
89
|
+
"warn/scrapers/in.py",
|
|
90
|
+
"warn/scrapers/ca.py",
|
|
91
|
+
"warn/scrapers/hi.py",
|
|
92
|
+
"warn/scrapers/ak.py",
|
|
93
|
+
"warn/scrapers/ri.py",
|
|
94
|
+
"warn/scrapers/ny.py",
|
|
95
|
+
"warn/scrapers/pa.py",
|
|
96
|
+
"warn/scrapers/dc.py",
|
|
97
|
+
"warn/scrapers/ct.py",
|
|
98
|
+
"warn/scrapers/mo.py",
|
|
99
|
+
"warn/scrapers/ok.py",
|
|
100
|
+
"warn/scrapers/tn.py",
|
|
101
|
+
"warn/scrapers/ks.py",
|
|
102
|
+
"warn/scrapers/oh.py",
|
|
103
|
+
"warn/scrapers/id.py",
|
|
104
|
+
"warn/scrapers/nm.py",
|
|
105
|
+
"warn/scrapers/me.py",
|
|
106
|
+
"warn/scrapers/va.py",
|
|
107
|
+
"warn/scrapers/ne.py",
|
|
108
|
+
"warn/scrapers/sd.py",
|
|
109
|
+
"warn/scrapers/ms.py",
|
|
110
|
+
"warn/platforms/__init__.py",
|
|
111
|
+
"warn/platforms/job_center/__init__.py",
|
|
112
|
+
"warn/platforms/job_center/utils.py",
|
|
113
|
+
"warn/platforms/job_center/cache.py",
|
|
114
|
+
"warn/platforms/job_center/site.py",
|
|
115
|
+
"warn/platforms/job_center/urls.py",
|
|
116
|
+
"warn/pdfrodent/__init__.py",
|
|
117
|
+
"warn/pdfrodent/pdfrodent.py",
|
|
118
|
+
"tests/__init__.py",
|
|
119
|
+
"tests/test_job_center.py",
|
|
120
|
+
"tests/test_job_center_cache.py",
|
|
121
|
+
"tests/test_openpyxl.py",
|
|
122
|
+
"tests/conftest.py",
|
|
123
|
+
"tests/test_cache.py",
|
|
124
|
+
"tests/test_delete.py",
|
|
125
|
+
"tests/fixtures/2021_page_2.html",
|
|
126
|
+
"tests/fixtures/2021_page_1.html",
|
|
127
|
+
"tests/cassettes/test_scrape_integration.yaml",
|
|
128
|
+
"tests/cassettes/test_cached_search_results.yaml",
|
|
129
|
+
"tests/cassettes/test_no_results.yaml",
|
|
130
|
+
"tests/cassettes/test_paged_results.yaml",
|
|
131
|
+
"tests/cassettes/test_missing_detail_page_values.yaml",
|
|
132
|
+
"tests/cassettes/test_cached_detail_pages.yaml",
|
|
133
|
+
".github/dependabot-disabled.yml",
|
|
134
|
+
".github/workflows/continuous-deployment.yml",
|
|
135
|
+
".github/workflows/continuous-deployment.yml.broken-tests"
|
|
136
|
+
]
|
|
137
|
+
}
|
|
File without changes
|
{warn_scraper-1.2.156.dev0.dist-info → warn_scraper-1.2.158.dev0.dist-info}/entry_points.txt
RENAMED
|
File without changes
|
{warn_scraper-1.2.156.dev0.dist-info → warn_scraper-1.2.158.dev0.dist-info}/licenses/LICENSE
RENAMED
|
File without changes
|
|
File without changes
|