Repository navigation
Release 0.1.8: security hardening, bug fixes, offline tests and CI - #3
Merged
Merged
Conversation
Security - Timeouts on every request (default (10, 30) seconds, overridable). - Response size caps (max_page_bytes, max_image_bytes), enforced from Content-Length and while streaming. - Redirects followed hop by hop, each hop validated; max_redirects bounds the chain. Only http/https are fetched. - Child links must stay on the same domain after redirects. - New block_private_addresses flag (default False) to refuse non-public targets, applied to pages and images. - CSV formula injection neutralised. - Safe, unique image file names; corrupt and decompression-bomb images are skipped instead of crashing the run. - requests>=2.32.4 (CVE-2024-47081), pillow>=10.3.0 (CVE-2024-28219). - CI: actions pinned to commit SHAs, least-privilege permissions, no persisted checkout credentials, PyPI token only in the publish job. Bug fixes - Inline markup no longer glues words; nested containers no longer repeat text; head/title/script/style/template/comments excluded; <br> yields line breaks. - links mode returns img/video/audio/source URLs, absolute, http(s) only. - unseen mode includes script data. - 4xx/5xx pages are skipped instead of being scraped. - Each page and each image is fetched once. - Images without src are skipped; empty image names no longer crash. - rate_limit is shared across threads. - Fragments and host/port variants are de-duplicated. - Output is deterministic (discovery order); de-duplication runs after the crawl. Duplicate similarity measured against the larger text, so short items no longer swallow unrelated paragraphs. - Failed pages are skipped and logged (logger 'pywebscrapr') instead of aborting the run and discarding output. - Links files: UTF-8 (BOM tolerated), blank lines ignored. - Charset taken from HTTP header or meta tag; <base href> honoured. - max_links_to_follow counts child links only; 0 means no child links. - Invalid options raise ValueError early. Packaging, CI and tests - Version defined once in pywebscrapr/__init__.py (__version__). - beautifulsoup4 replaces bs4; Python >=3.9. - Workflow tests on 3.9/3.12/3.13 for pushes and PRs; publishing runs only for tags that pass the tests and match __version__. - tests.py rewritten as an offline suite on local fixture servers, plus an opt-in live test (PYWEBSCRAPR_LIVE_TESTS=1). - README: consolidated 0.1.8 changelog and usage notes. Co-authored-by: arena-agent <297053741+arena-agent@users.noreply.github.com>
…ions to README Co-authored-by: arena-agent <297053741+arena-agent@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Release 0.1.8: security hardening, bug fixes, an offline test suite, and CI/publishing changes. Full changelog is in
README.mdunder Changes in 0.1.8.Breaking changes
pywebscrapr) instead of aborting the run.max_links_to_followcounts child links only;0means no child links.rate_limitis now global across threads.URLvalues are final URLs after redirects.PyWebScrapr/0.1.8 (...)(passuser_agent=Nonefor the requests default).Security
(10, 30)), overridable.max_page_bytes,max_image_bytes), enforced fromContent-Lengthand while streaming.max_redirects); only http/https fetched.block_private_addressesflag (defaultFalse, so private hosts remain allowed by default).requests>=2.32.4(CVE-2024-47081),pillow>=10.3.0(CVE-2024-28219).permissions: contents: read, no persisted checkout credentials, PyPI token only in the publish job.Bug fixes
<head>/<title>/<script>/<style>/<template>/comments excluded;<br>gives line breaks.linksmode returns img/video/audio/source URLs (absolute, http(s) only);unseenmode includes script data.srcskipped; empty image names no longer crash.<meta charset>;<base href>honoured.ValueErrorearly.Packaging, CI, tests
pywebscrapr/__init__.py(__version__);setup.pyreads it.bs4replaced bybeautifulsoup4; build withpython -m build.__version__, using the existingPYPI_API_TOKENsecret.tests.pyrewritten: 39 offline tests against local fixture servers, plus an opt-in live test (PYWEBSCRAPR_LIVE_TESTS=1).Verification
python -m unittest -v tests: 39 offline tests pass, 1 live test skipped by default. Run three times to check the timing-sensitive tests (timeout, rate limit).python -m buildproducespywebscrapr-0.1.8sdist and wheel; the wheel contains only the package.pyflakesclean on the package and tests.Notes for reviewers
block_private_addressesdoes not stop DNS rebinding).0.1.8) is pushed.