graph-crawler 5.3.2__tar.gz → 5.3.4__tar.gz

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.
Files changed (957) hide show
  1. graph_crawler-5.3.4/CHANGELOG.md +429 -0
  2. graph_crawler-5.3.4/LICENSE +21 -0
  3. graph_crawler-5.3.4/MANIFEST.in +16 -0
  4. graph_crawler-5.3.4/PKG-INFO +522 -0
  5. graph_crawler-5.3.4/README.md +401 -0
  6. graph_crawler-5.3.4/graph_crawler/__init__.py +496 -0
  7. graph_crawler-5.3.4/graph_crawler/__version__.py +8 -0
  8. graph_crawler-5.3.4/graph_crawler/ai/__init__.py +50 -0
  9. graph_crawler-5.3.4/graph_crawler/api/__init__.py +28 -0
  10. graph_crawler-5.3.4/graph_crawler/api/_core.py +285 -0
  11. graph_crawler-5.3.4/graph_crawler/api/_distributed.py +172 -0
  12. graph_crawler-5.3.4/graph_crawler/api/_shared.py +110 -0
  13. graph_crawler-5.3.4/graph_crawler/api/_sitemap_distributed.py +238 -0
  14. graph_crawler-5.3.4/graph_crawler/api/async_.py +325 -0
  15. graph_crawler-5.3.4/graph_crawler/api/cli.py +440 -0
  16. graph_crawler-5.3.4/graph_crawler/api/client/__init__.py +8 -0
  17. graph_crawler-5.3.4/graph_crawler/api/client/client.py +473 -0
  18. graph_crawler-5.3.4/graph_crawler/api/history_manager.py +55 -0
  19. graph_crawler-5.3.4/graph_crawler/api/project_init.py +196 -0
  20. graph_crawler-5.3.4/graph_crawler/api/server/__init__.py +18 -0
  21. graph_crawler-5.3.4/graph_crawler/api/server/crawl_monitor.py +145 -0
  22. graph_crawler-5.3.4/graph_crawler/api/server/dashboard.py +221 -0
  23. graph_crawler-5.3.4/graph_crawler/api/server/rest_api.py +704 -0
  24. graph_crawler-5.3.4/graph_crawler/api/server/webhooks.py +421 -0
  25. graph_crawler-5.3.4/graph_crawler/api/server/websocket_manager.py +89 -0
  26. graph_crawler-5.3.4/graph_crawler/api/stats_collector.py +88 -0
  27. graph_crawler-5.3.4/graph_crawler/api/sync.py +540 -0
  28. graph_crawler-5.3.4/graph_crawler/application/__init__.py +38 -0
  29. graph_crawler-5.3.4/graph_crawler/application/bootstrap.py +211 -0
  30. graph_crawler-5.3.4/graph_crawler/application/context/__init__.py +31 -0
  31. graph_crawler-5.3.4/graph_crawler/application/context/dependency_registry.py +354 -0
  32. graph_crawler-5.3.4/graph_crawler/application/context/graph_context.py +217 -0
  33. graph_crawler-5.3.4/graph_crawler/application/context/merge_context.py +221 -0
  34. graph_crawler-5.3.4/graph_crawler/application/dto/__init__.py +67 -0
  35. graph_crawler-5.3.4/graph_crawler/application/dto/edge_dto.py +25 -0
  36. graph_crawler-5.3.4/graph_crawler/application/dto/graph_dto.py +27 -0
  37. graph_crawler-5.3.4/graph_crawler/application/dto/mappers/__init__.py +14 -0
  38. graph_crawler-5.3.4/graph_crawler/application/dto/mappers/edge_mapper.py +149 -0
  39. graph_crawler-5.3.4/graph_crawler/application/dto/mappers/graph_mapper.py +622 -0
  40. graph_crawler-5.3.4/graph_crawler/application/dto/mappers/node_data_codec.py +190 -0
  41. graph_crawler-5.3.4/graph_crawler/application/dto/mappers/node_mapper.py +417 -0
  42. graph_crawler-5.3.4/graph_crawler/application/dto/node_dto.py +27 -0
  43. graph_crawler-5.3.4/graph_crawler/application/dto/utils.py +272 -0
  44. graph_crawler-5.3.4/graph_crawler/application/services/__init__.py +60 -0
  45. graph_crawler-5.3.4/graph_crawler/application/services/application_container.py +208 -0
  46. graph_crawler-5.3.4/graph_crawler/application/services/driver_factory.py +147 -0
  47. graph_crawler-5.3.4/graph_crawler/application/services/exporters/__init__.py +26 -0
  48. graph_crawler-5.3.4/graph_crawler/application/services/exporters/base_exporter.py +150 -0
  49. graph_crawler-5.3.4/graph_crawler/application/services/exporters/csv_exporter.py +318 -0
  50. graph_crawler-5.3.4/graph_crawler/application/services/exporters/edge_exporter.py +432 -0
  51. graph_crawler-5.3.4/graph_crawler/application/services/exporters/excel_exporter.py +301 -0
  52. graph_crawler-5.3.4/graph_crawler/application/services/exporters/jsonl_exporter.py +290 -0
  53. graph_crawler-5.3.4/graph_crawler/application/services/exporters/node_exporter.py +284 -0
  54. graph_crawler-5.3.4/graph_crawler/application/services/exporters/parquet_exporter.py +248 -0
  55. graph_crawler-5.3.4/graph_crawler/application/services/exporters/sql_exporter.py +267 -0
  56. graph_crawler-5.3.4/graph_crawler/application/services/finalize.py +115 -0
  57. graph_crawler-5.3.4/graph_crawler/application/services/low_memory_graph_saver.py +337 -0
  58. graph_crawler-5.3.4/graph_crawler/application/services/resource_budget.py +179 -0
  59. graph_crawler-5.3.4/graph_crawler/application/services/scheduling/__init__.py +12 -0
  60. graph_crawler-5.3.4/graph_crawler/application/services/scheduling/rule_based_scheduler.py +105 -0
  61. graph_crawler-5.3.4/graph_crawler/application/services/storage_factory.py +195 -0
  62. graph_crawler-5.3.4/graph_crawler/application/use_cases/__init__.py +11 -0
  63. graph_crawler-5.3.4/graph_crawler/application/use_cases/crawling/__init__.py +81 -0
  64. graph_crawler-5.3.4/graph_crawler/application/use_cases/crawling/adaptive_throttler.py +373 -0
  65. graph_crawler-5.3.4/graph_crawler/application/use_cases/crawling/async_bridge.py +45 -0
  66. graph_crawler-5.3.4/graph_crawler/application/use_cases/crawling/base_spider.py +155 -0
  67. graph_crawler-5.3.4/graph_crawler/application/use_cases/crawling/celery_batch_spider.py +656 -0
  68. graph_crawler-5.3.4/graph_crawler/application/use_cases/crawling/celery_spider.py +445 -0
  69. graph_crawler-5.3.4/graph_crawler/application/use_cases/crawling/checkpoint.py +421 -0
  70. graph_crawler-5.3.4/graph_crawler/application/use_cases/crawling/crawl_coordinator.py +1049 -0
  71. graph_crawler-5.3.4/graph_crawler/application/use_cases/crawling/dead_letter_queue.py +413 -0
  72. graph_crawler-5.3.4/graph_crawler/application/use_cases/crawling/domain_rate_limiter.py +262 -0
  73. graph_crawler-5.3.4/graph_crawler/application/use_cases/crawling/filters/__init__.py +10 -0
  74. graph_crawler-5.3.4/graph_crawler/application/use_cases/crawling/filters/base.py +74 -0
  75. graph_crawler-5.3.4/graph_crawler/application/use_cases/crawling/filters/domain_filter.py +195 -0
  76. graph_crawler-5.3.4/graph_crawler/application/use_cases/crawling/filters/domain_patterns.py +30 -0
  77. graph_crawler-5.3.4/graph_crawler/application/use_cases/crawling/filters/path_filter.py +95 -0
  78. graph_crawler-5.3.4/graph_crawler/application/use_cases/crawling/incremental_strategy.py +239 -0
  79. graph_crawler-5.3.4/graph_crawler/application/use_cases/crawling/link_processor.py +885 -0
  80. graph_crawler-5.3.4/graph_crawler/application/use_cases/crawling/multiprocess_spider.py +511 -0
  81. graph_crawler-5.3.4/graph_crawler/application/use_cases/crawling/node_scanner.py +867 -0
  82. graph_crawler-5.3.4/graph_crawler/application/use_cases/crawling/parsers/__init__.py +6 -0
  83. graph_crawler-5.3.4/graph_crawler/application/use_cases/crawling/parsers/base.py +73 -0
  84. graph_crawler-5.3.4/graph_crawler/application/use_cases/crawling/parsers/html_parser.py +154 -0
  85. graph_crawler-5.3.4/graph_crawler/application/use_cases/crawling/progress_tracker.py +235 -0
  86. graph_crawler-5.3.4/graph_crawler/application/use_cases/crawling/scheduler.py +757 -0
  87. graph_crawler-5.3.4/graph_crawler/application/use_cases/crawling/serialization_mixin.py +218 -0
  88. graph_crawler-5.3.4/graph_crawler/application/use_cases/crawling/sitemap_parser.py +657 -0
  89. graph_crawler-5.3.4/graph_crawler/application/use_cases/crawling/sitemap_processor.py +401 -0
  90. graph_crawler-5.3.4/graph_crawler/application/use_cases/crawling/sitemap_spider.py +608 -0
  91. graph_crawler-5.3.4/graph_crawler/application/use_cases/crawling/spider.py +855 -0
  92. graph_crawler-5.3.4/graph_crawler/application/use_cases/crawling/spider_lifecycle.py +108 -0
  93. graph_crawler-5.3.4/graph_crawler/application/use_cases/crawling/worker_pool.py +154 -0
  94. graph_crawler-5.3.4/graph_crawler/application/use_cases/graph_export.py +504 -0
  95. graph_crawler-5.3.4/graph_crawler/application/use_cases/graph_merge/__init__.py +33 -0
  96. graph_crawler-5.3.4/graph_crawler/application/use_cases/graph_merge/graph_operations.py +632 -0
  97. graph_crawler-5.3.4/graph_crawler/application/use_cases/graph_merge/merge_strategies.py +348 -0
  98. graph_crawler-5.3.4/graph_crawler/data/__init__.py +28 -0
  99. graph_crawler-5.3.4/graph_crawler/data/backends/__init__.py +21 -0
  100. graph_crawler-5.3.4/graph_crawler/data/backends/memory.py +486 -0
  101. graph_crawler-5.3.4/graph_crawler/data/backends/sqlite.py +1866 -0
  102. graph_crawler-5.3.4/graph_crawler/data/interfaces.py +563 -0
  103. graph_crawler-5.3.4/graph_crawler/domain/__init__.py +62 -0
  104. graph_crawler-5.3.4/graph_crawler/domain/context/__init__.py +14 -0
  105. graph_crawler-5.3.4/graph_crawler/domain/context/crawl_context.py +531 -0
  106. graph_crawler-5.3.4/graph_crawler/domain/entities/__init__.py +32 -0
  107. graph_crawler-5.3.4/graph_crawler/domain/entities/edge.py +345 -0
  108. graph_crawler-5.3.4/graph_crawler/domain/entities/edge_analysis.py +223 -0
  109. graph_crawler-5.3.4/graph_crawler/domain/entities/graph.py +4169 -0
  110. graph_crawler-5.3.4/graph_crawler/domain/entities/graph_operations.py +30 -0
  111. graph_crawler-5.3.4/graph_crawler/domain/entities/graph_statistics.py +10 -0
  112. graph_crawler-5.3.4/graph_crawler/domain/entities/merge_strategies.py +33 -0
  113. graph_crawler-5.3.4/graph_crawler/domain/entities/node.py +886 -0
  114. graph_crawler-5.3.4/graph_crawler/domain/entities/redirect_mode.py +23 -0
  115. graph_crawler-5.3.4/graph_crawler/domain/entities/registries.py +223 -0
  116. graph_crawler-5.3.4/graph_crawler/domain/entities/sitemap_node.py +74 -0
  117. graph_crawler-5.3.4/graph_crawler/domain/entities/strategies.py +202 -0
  118. graph_crawler-5.3.4/graph_crawler/domain/events/__init__.py +162 -0
  119. graph_crawler-5.3.4/graph_crawler/domain/events/base.py +60 -0
  120. graph_crawler-5.3.4/graph_crawler/domain/events/crawl.py +112 -0
  121. graph_crawler-5.3.4/graph_crawler/domain/events/edge.py +43 -0
  122. graph_crawler-5.3.4/graph_crawler/domain/events/event_bus.py +250 -0
  123. graph_crawler-5.3.4/graph_crawler/domain/events/events.py +313 -0
  124. graph_crawler-5.3.4/graph_crawler/domain/events/fetch.py +120 -0
  125. graph_crawler-5.3.4/graph_crawler/domain/events/idempotent_subscriber.py +120 -0
  126. graph_crawler-5.3.4/graph_crawler/domain/events/legacy_type_map.py +45 -0
  127. graph_crawler-5.3.4/graph_crawler/domain/events/llm.py +148 -0
  128. graph_crawler-5.3.4/graph_crawler/domain/events/node.py +111 -0
  129. graph_crawler-5.3.4/graph_crawler/domain/events/plugin.py +92 -0
  130. graph_crawler-5.3.4/graph_crawler/domain/events/scheduler.py +98 -0
  131. graph_crawler-5.3.4/graph_crawler/domain/events/storage.py +161 -0
  132. graph_crawler-5.3.4/graph_crawler/domain/interfaces/__init__.py +113 -0
  133. graph_crawler-5.3.4/graph_crawler/domain/interfaces/adapter.py +29 -0
  134. graph_crawler-5.3.4/graph_crawler/domain/interfaces/control_channel.py +381 -0
  135. graph_crawler-5.3.4/graph_crawler/domain/interfaces/crawl_context.py +49 -0
  136. graph_crawler-5.3.4/graph_crawler/domain/interfaces/distributed_spider.py +62 -0
  137. graph_crawler-5.3.4/graph_crawler/domain/interfaces/driver.py +87 -0
  138. graph_crawler-5.3.4/graph_crawler/domain/interfaces/event_bus.py +61 -0
  139. graph_crawler-5.3.4/graph_crawler/domain/interfaces/exporters.py +69 -0
  140. graph_crawler-5.3.4/graph_crawler/domain/interfaces/filter.py +19 -0
  141. graph_crawler-5.3.4/graph_crawler/domain/interfaces/merge_context.py +52 -0
  142. graph_crawler-5.3.4/graph_crawler/domain/interfaces/node_interfaces.py +389 -0
  143. graph_crawler-5.3.4/graph_crawler/domain/interfaces/parser.py +88 -0
  144. graph_crawler-5.3.4/graph_crawler/domain/interfaces/plugin_manager.py +53 -0
  145. graph_crawler-5.3.4/graph_crawler/domain/interfaces/processor.py +11 -0
  146. graph_crawler-5.3.4/graph_crawler/domain/interfaces/scanner.py +57 -0
  147. graph_crawler-5.3.4/graph_crawler/domain/interfaces/scheduler.py +43 -0
  148. graph_crawler-5.3.4/graph_crawler/domain/interfaces/scheduling/__init__.py +40 -0
  149. graph_crawler-5.3.4/graph_crawler/domain/interfaces/scheduling/frontier.py +97 -0
  150. graph_crawler-5.3.4/graph_crawler/domain/interfaces/scheduling/scheduler.py +107 -0
  151. graph_crawler-5.3.4/graph_crawler/domain/interfaces/spider.py +63 -0
  152. graph_crawler-5.3.4/graph_crawler/domain/interfaces/stop_condition.py +211 -0
  153. graph_crawler-5.3.4/graph_crawler/domain/interfaces/storage/__init__.py +43 -0
  154. graph_crawler-5.3.4/graph_crawler/domain/interfaces/storage/base.py +68 -0
  155. graph_crawler-5.3.4/graph_crawler/domain/interfaces/storage/eviction.py +98 -0
  156. graph_crawler-5.3.4/graph_crawler/domain/interfaces/storage/queue.py +234 -0
  157. graph_crawler-5.3.4/graph_crawler/domain/services/__init__.py +216 -0
  158. graph_crawler-5.3.4/graph_crawler/domain/services/adjacency_maintenance.py +95 -0
  159. graph_crawler-5.3.4/graph_crawler/domain/services/cycle_detection.py +92 -0
  160. graph_crawler-5.3.4/graph_crawler/domain/services/degree_ranking.py +47 -0
  161. graph_crawler-5.3.4/graph_crawler/domain/services/depth_context.py +123 -0
  162. graph_crawler-5.3.4/graph_crawler/domain/services/display_title.py +47 -0
  163. graph_crawler-5.3.4/graph_crawler/domain/services/duplicate_detection.py +141 -0
  164. graph_crawler-5.3.4/graph_crawler/domain/services/duplicate_selector.py +127 -0
  165. graph_crawler-5.3.4/graph_crawler/domain/services/duplicate_stats.py +63 -0
  166. graph_crawler-5.3.4/graph_crawler/domain/services/edge_filter.py +82 -0
  167. graph_crawler-5.3.4/graph_crawler/domain/services/edge_statistics.py +110 -0
  168. graph_crawler-5.3.4/graph_crawler/domain/services/eviction_policy.py +83 -0
  169. graph_crawler-5.3.4/graph_crawler/domain/services/graph_query_cascade.py +178 -0
  170. graph_crawler-5.3.4/graph_crawler/domain/services/graph_statistics.py +186 -0
  171. graph_crawler-5.3.4/graph_crawler/domain/services/graph_traversal.py +150 -0
  172. graph_crawler-5.3.4/graph_crawler/domain/services/language_versions.py +73 -0
  173. graph_crawler-5.3.4/graph_crawler/domain/services/lsh_index.py +99 -0
  174. graph_crawler-5.3.4/graph_crawler/domain/services/minimap_builder.py +147 -0
  175. graph_crawler-5.3.4/graph_crawler/domain/services/node_content_resolver.py +128 -0
  176. graph_crawler-5.3.4/graph_crawler/domain/services/node_view_builder.py +163 -0
  177. graph_crawler-5.3.4/graph_crawler/domain/services/pagination_guards.py +136 -0
  178. graph_crawler-5.3.4/graph_crawler/domain/services/predicate_ops.py +77 -0
  179. graph_crawler-5.3.4/graph_crawler/domain/services/schema_filter.py +138 -0
  180. graph_crawler-5.3.4/graph_crawler/domain/services/search_haystack.py +102 -0
  181. graph_crawler-5.3.4/graph_crawler/domain/services/simhash_clustering.py +96 -0
  182. graph_crawler-5.3.4/graph_crawler/domain/services/simhash_fallback.py +59 -0
  183. graph_crawler-5.3.4/graph_crawler/domain/services/similarity_ranking.py +62 -0
  184. graph_crawler-5.3.4/graph_crawler/domain/services/text_search.py +157 -0
  185. graph_crawler-5.3.4/graph_crawler/domain/services/url_clustering.py +88 -0
  186. graph_crawler-5.3.4/graph_crawler/domain/services/url_deduplication.py +101 -0
  187. graph_crawler-5.3.4/graph_crawler/domain/services/url_normalizer.py +117 -0
  188. graph_crawler-5.3.4/graph_crawler/domain/services/url_rule_matcher.py +111 -0
  189. graph_crawler-5.3.4/graph_crawler/domain/services/url_tree_builder.py +197 -0
  190. graph_crawler-5.3.4/graph_crawler/domain/value_objects/__init__.py +88 -0
  191. graph_crawler-5.3.4/graph_crawler/domain/value_objects/configs.py +891 -0
  192. graph_crawler-5.3.4/graph_crawler/domain/value_objects/domain_patterns.py +71 -0
  193. graph_crawler-5.3.4/graph_crawler/domain/value_objects/fetch_options.py +57 -0
  194. graph_crawler-5.3.4/graph_crawler/domain/value_objects/html_document.py +59 -0
  195. graph_crawler-5.3.4/graph_crawler/domain/value_objects/lifecycle.py +30 -0
  196. graph_crawler-5.3.4/graph_crawler/domain/value_objects/models.py +1315 -0
  197. graph_crawler-5.3.4/graph_crawler/domain/value_objects/page_actions.py +72 -0
  198. graph_crawler-5.3.4/graph_crawler/domain/value_objects/redirect_hop.py +49 -0
  199. graph_crawler-5.3.4/graph_crawler/domain/value_objects/scheduling/__init__.py +23 -0
  200. graph_crawler-5.3.4/graph_crawler/domain/value_objects/scheduling/crawl_request.py +153 -0
  201. graph_crawler-5.3.4/graph_crawler/domain/value_objects/scheduling/retry_policy.py +109 -0
  202. graph_crawler-5.3.4/graph_crawler/domain/value_objects/settings.py +350 -0
  203. graph_crawler-5.3.4/graph_crawler/domain/value_objects/url_normalization.py +497 -0
  204. graph_crawler-5.3.4/graph_crawler/domain/value_objects/views.py +293 -0
  205. graph_crawler-5.3.4/graph_crawler/extensions/__init__.py +1 -0
  206. graph_crawler-5.3.4/graph_crawler/extensions/middleware/__init__.py +65 -0
  207. graph_crawler-5.3.4/graph_crawler/extensions/middleware/base.py +136 -0
  208. graph_crawler-5.3.4/graph_crawler/extensions/middleware/cache_middleware.py +277 -0
  209. graph_crawler-5.3.4/graph_crawler/extensions/middleware/chain.py +155 -0
  210. graph_crawler-5.3.4/graph_crawler/extensions/middleware/error_recovery_middleware.py +442 -0
  211. graph_crawler-5.3.4/graph_crawler/extensions/middleware/logging_middleware.py +108 -0
  212. graph_crawler-5.3.4/graph_crawler/extensions/middleware/proxy_health.py +141 -0
  213. graph_crawler-5.3.4/graph_crawler/extensions/middleware/proxy_middleware.py +209 -0
  214. graph_crawler-5.3.4/graph_crawler/extensions/middleware/proxy_models.py +80 -0
  215. graph_crawler-5.3.4/graph_crawler/extensions/middleware/proxy_selection.py +87 -0
  216. graph_crawler-5.3.4/graph_crawler/extensions/middleware/rate_limit_middleware.py +262 -0
  217. graph_crawler-5.3.4/graph_crawler/extensions/middleware/request_response_middleware.py +476 -0
  218. graph_crawler-5.3.4/graph_crawler/extensions/middleware/retry_middleware.py +279 -0
  219. graph_crawler-5.3.4/graph_crawler/extensions/middleware/robots_cache.py +85 -0
  220. graph_crawler-5.3.4/graph_crawler/extensions/middleware/robots_middleware.py +110 -0
  221. graph_crawler-5.3.4/graph_crawler/extensions/middleware/robots_validator.py +60 -0
  222. graph_crawler-5.3.4/graph_crawler/extensions/middleware/user_agent_middleware.py +251 -0
  223. graph_crawler-5.3.4/graph_crawler/extensions/plugins/__init__.py +57 -0
  224. graph_crawler-5.3.4/graph_crawler/extensions/plugins/builtin/__init__.py +7 -0
  225. graph_crawler-5.3.4/graph_crawler/extensions/plugins/builtin/stats_export_plugin.py +99 -0
  226. graph_crawler-5.3.4/graph_crawler/extensions/plugins/crawl_engine/__init__.py +24 -0
  227. graph_crawler-5.3.4/graph_crawler/extensions/plugins/crawl_engine/base.py +155 -0
  228. graph_crawler-5.3.4/graph_crawler/extensions/plugins/crawl_engine/priority_provider.py +247 -0
  229. graph_crawler-5.3.4/graph_crawler/extensions/plugins/crawl_engine/smart_crawl.py +296 -0
  230. graph_crawler-5.3.4/graph_crawler/extensions/plugins/engine/__init__.py +128 -0
  231. graph_crawler-5.3.4/graph_crawler/extensions/plugins/engine/anti_bot_detection.py +55 -0
  232. graph_crawler-5.3.4/graph_crawler/extensions/plugins/engine/anti_bot_playwright.py +88 -0
  233. graph_crawler-5.3.4/graph_crawler/extensions/plugins/engine/anti_bot_scripts.py +136 -0
  234. graph_crawler-5.3.4/graph_crawler/extensions/plugins/engine/anti_bot_stealth.py +177 -0
  235. graph_crawler-5.3.4/graph_crawler/extensions/plugins/engine/base.py +121 -0
  236. graph_crawler-5.3.4/graph_crawler/extensions/plugins/engine/captcha/__init__.py +22 -0
  237. graph_crawler-5.3.4/graph_crawler/extensions/plugins/engine/captcha/detector.py +94 -0
  238. graph_crawler-5.3.4/graph_crawler/extensions/plugins/engine/captcha/models.py +74 -0
  239. graph_crawler-5.3.4/graph_crawler/extensions/plugins/engine/captcha/plugin.py +228 -0
  240. graph_crawler-5.3.4/graph_crawler/extensions/plugins/engine/captcha/services.py +389 -0
  241. graph_crawler-5.3.4/graph_crawler/extensions/plugins/node/__init__.py +86 -0
  242. graph_crawler-5.3.4/graph_crawler/extensions/plugins/node/base.py +520 -0
  243. graph_crawler-5.3.4/graph_crawler/extensions/plugins/node/content_extractors/__init__.py +15 -0
  244. graph_crawler-5.3.4/graph_crawler/extensions/plugins/node/content_extractors/base.py +82 -0
  245. graph_crawler-5.3.4/graph_crawler/extensions/plugins/node/content_extractors/goose3_extractor.py +80 -0
  246. graph_crawler-5.3.4/graph_crawler/extensions/plugins/node/content_extractors/newspaper_extractor.py +93 -0
  247. graph_crawler-5.3.4/graph_crawler/extensions/plugins/node/content_extractors/plugin.py +132 -0
  248. graph_crawler-5.3.4/graph_crawler/extensions/plugins/node/content_extractors/readability_extractor.py +91 -0
  249. graph_crawler-5.3.4/graph_crawler/extensions/plugins/node/defaults.py +32 -0
  250. graph_crawler-5.3.4/graph_crawler/extensions/plugins/node/extractors/__init__.py +30 -0
  251. graph_crawler-5.3.4/graph_crawler/extensions/plugins/node/extractors/email_extractor.py +146 -0
  252. graph_crawler-5.3.4/graph_crawler/extensions/plugins/node/extractors/phone_extractor.py +136 -0
  253. graph_crawler-5.3.4/graph_crawler/extensions/plugins/node/extractors/price_extractor.py +137 -0
  254. graph_crawler-5.3.4/graph_crawler/extensions/plugins/node/links.py +184 -0
  255. graph_crawler-5.3.4/graph_crawler/extensions/plugins/node/markdown_plugin.py +249 -0
  256. graph_crawler-5.3.4/graph_crawler/extensions/plugins/node/metadata.py +384 -0
  257. graph_crawler-5.3.4/graph_crawler/extensions/plugins/node/smart_page_finder.py +749 -0
  258. graph_crawler-5.3.4/graph_crawler/extensions/plugins/node/structured_data/__init__.py +51 -0
  259. graph_crawler-5.3.4/graph_crawler/extensions/plugins/node/structured_data/constants.py +27 -0
  260. graph_crawler-5.3.4/graph_crawler/extensions/plugins/node/structured_data/exceptions.py +18 -0
  261. graph_crawler-5.3.4/graph_crawler/extensions/plugins/node/structured_data/extractor.py +361 -0
  262. graph_crawler-5.3.4/graph_crawler/extensions/plugins/node/structured_data/options.py +62 -0
  263. graph_crawler-5.3.4/graph_crawler/extensions/plugins/node/structured_data/parsers/__init__.py +25 -0
  264. graph_crawler-5.3.4/graph_crawler/extensions/plugins/node/structured_data/parsers/base.py +43 -0
  265. graph_crawler-5.3.4/graph_crawler/extensions/plugins/node/structured_data/parsers/jsonld.py +331 -0
  266. graph_crawler-5.3.4/graph_crawler/extensions/plugins/node/structured_data/parsers/microdata.py +117 -0
  267. graph_crawler-5.3.4/graph_crawler/extensions/plugins/node/structured_data/parsers/opengraph.py +66 -0
  268. graph_crawler-5.3.4/graph_crawler/extensions/plugins/node/structured_data/parsers/rdfa.py +122 -0
  269. graph_crawler-5.3.4/graph_crawler/extensions/plugins/node/structured_data/parsers/twitter.py +66 -0
  270. graph_crawler-5.3.4/graph_crawler/extensions/plugins/node/structured_data/plugin.py +132 -0
  271. graph_crawler-5.3.4/graph_crawler/extensions/plugins/node/structured_data/result.py +233 -0
  272. graph_crawler-5.3.4/graph_crawler/extensions/plugins/node/text.py +76 -0
  273. graph_crawler-5.3.4/graph_crawler/extensions/plugins/node/url_normalizer.py +363 -0
  274. graph_crawler-5.3.4/graph_crawler/extensions/plugins/registry.py +97 -0
  275. graph_crawler-5.3.4/graph_crawler/infrastructure/__init__.py +1 -0
  276. graph_crawler-5.3.4/graph_crawler/infrastructure/adapters/__init__.py +60 -0
  277. graph_crawler-5.3.4/graph_crawler/infrastructure/adapters/base.py +498 -0
  278. graph_crawler-5.3.4/graph_crawler/infrastructure/adapters/selectolax_adapter.py +233 -0
  279. graph_crawler-5.3.4/graph_crawler/infrastructure/messaging/__init__.py +37 -0
  280. graph_crawler-5.3.4/graph_crawler/infrastructure/messaging/celery_app.py +202 -0
  281. graph_crawler-5.3.4/graph_crawler/infrastructure/messaging/celery_batch.py +284 -0
  282. graph_crawler-5.3.4/graph_crawler/infrastructure/messaging/celery_job_task.py +415 -0
  283. graph_crawler-5.3.4/graph_crawler/infrastructure/messaging/celery_unified.py +419 -0
  284. graph_crawler-5.3.4/graph_crawler/infrastructure/messaging/config.py +201 -0
  285. graph_crawler-5.3.4/graph_crawler/infrastructure/messaging/easy_crawler.py +279 -0
  286. graph_crawler-5.3.4/graph_crawler/infrastructure/messaging/worker_api.py +607 -0
  287. graph_crawler-5.3.4/graph_crawler/infrastructure/persistence/__init__.py +135 -0
  288. graph_crawler-5.3.4/graph_crawler/infrastructure/persistence/auto_storage.py +336 -0
  289. graph_crawler-5.3.4/graph_crawler/infrastructure/persistence/base.py +111 -0
  290. graph_crawler-5.3.4/graph_crawler/infrastructure/persistence/eviction.py +100 -0
  291. graph_crawler-5.3.4/graph_crawler/infrastructure/persistence/graph_repository.py +401 -0
  292. graph_crawler-5.3.4/graph_crawler/infrastructure/persistence/json/__init__.py +10 -0
  293. graph_crawler-5.3.4/graph_crawler/infrastructure/persistence/json_storage.py +375 -0
  294. graph_crawler-5.3.4/graph_crawler/infrastructure/persistence/lmdb_eviction_storage.py +401 -0
  295. graph_crawler-5.3.4/graph_crawler/infrastructure/persistence/memory/__init__.py +1 -0
  296. graph_crawler-5.3.4/graph_crawler/infrastructure/persistence/memory_dedup_store.py +90 -0
  297. graph_crawler-5.3.4/graph_crawler/infrastructure/persistence/memory_frontier.py +180 -0
  298. graph_crawler-5.3.4/graph_crawler/infrastructure/persistence/memory_politeness_store.py +88 -0
  299. graph_crawler-5.3.4/graph_crawler/infrastructure/persistence/memory_storage.py +166 -0
  300. graph_crawler-5.3.4/graph_crawler/infrastructure/persistence/mongodb_storage.py +383 -0
  301. graph_crawler-5.3.4/graph_crawler/infrastructure/persistence/naming_strategy.py +174 -0
  302. graph_crawler-5.3.4/graph_crawler/infrastructure/persistence/postgresql_storage.py +449 -0
  303. graph_crawler-5.3.4/graph_crawler/infrastructure/persistence/protocols/__init__.py +1 -0
  304. graph_crawler-5.3.4/graph_crawler/infrastructure/persistence/redis_dedup_store.py +119 -0
  305. graph_crawler-5.3.4/graph_crawler/infrastructure/persistence/redis_politeness_store.py +122 -0
  306. graph_crawler-5.3.4/graph_crawler/infrastructure/persistence/repository.py +130 -0
  307. graph_crawler-5.3.4/graph_crawler/infrastructure/persistence/sqlite/__init__.py +10 -0
  308. graph_crawler-5.3.4/graph_crawler/infrastructure/persistence/sqlite_eviction_storage.py +918 -0
  309. graph_crawler-5.3.4/graph_crawler/infrastructure/persistence/sqlite_storage.py +775 -0
  310. graph_crawler-5.3.4/graph_crawler/infrastructure/persistence/unified/__init__.py +47 -0
  311. graph_crawler-5.3.4/graph_crawler/infrastructure/persistence/unified/file_job_storage.py +245 -0
  312. graph_crawler-5.3.4/graph_crawler/infrastructure/persistence/unified/file_queue_storage.py +248 -0
  313. graph_crawler-5.3.4/graph_crawler/infrastructure/persistence/unified/memory_job_storage.py +94 -0
  314. graph_crawler-5.3.4/graph_crawler/infrastructure/persistence/unified/memory_queue_storage.py +117 -0
  315. graph_crawler-5.3.4/graph_crawler/infrastructure/persistence/unified/postgresql_job_storage.py +317 -0
  316. graph_crawler-5.3.4/graph_crawler/infrastructure/persistence/unified/postgresql_queue_storage.py +364 -0
  317. graph_crawler-5.3.4/graph_crawler/infrastructure/persistence/unified/unified_storage.py +244 -0
  318. graph_crawler-5.3.4/graph_crawler/infrastructure/transport/__init__.py +135 -0
  319. graph_crawler-5.3.4/graph_crawler/infrastructure/transport/async_http/__init__.py +38 -0
  320. graph_crawler-5.3.4/graph_crawler/infrastructure/transport/async_http/config.py +47 -0
  321. graph_crawler-5.3.4/graph_crawler/infrastructure/transport/async_http/context.py +55 -0
  322. graph_crawler-5.3.4/graph_crawler/infrastructure/transport/async_http/driver.py +724 -0
  323. graph_crawler-5.3.4/graph_crawler/infrastructure/transport/async_http/driver_curl_cffi.py +407 -0
  324. graph_crawler-5.3.4/graph_crawler/infrastructure/transport/async_http/plugins/__init__.py +48 -0
  325. graph_crawler-5.3.4/graph_crawler/infrastructure/transport/async_http/plugins/autothrottle.py +484 -0
  326. graph_crawler-5.3.4/graph_crawler/infrastructure/transport/async_http/plugins/autothrottle_adaptive.py +1435 -0
  327. graph_crawler-5.3.4/graph_crawler/infrastructure/transport/async_http/plugins/headers.py +69 -0
  328. graph_crawler-5.3.4/graph_crawler/infrastructure/transport/async_http/plugins/http_cache.py +321 -0
  329. graph_crawler-5.3.4/graph_crawler/infrastructure/transport/async_http/plugins/rate_limiter.py +96 -0
  330. graph_crawler-5.3.4/graph_crawler/infrastructure/transport/async_http/plugins/retry.py +316 -0
  331. graph_crawler-5.3.4/graph_crawler/infrastructure/transport/async_http/stages.py +33 -0
  332. graph_crawler-5.3.4/graph_crawler/infrastructure/transport/base.py +349 -0
  333. graph_crawler-5.3.4/graph_crawler/infrastructure/transport/base_plugin.py +151 -0
  334. graph_crawler-5.3.4/graph_crawler/infrastructure/transport/compression/__init__.py +23 -0
  335. graph_crawler-5.3.4/graph_crawler/infrastructure/transport/compression/strategy.py +219 -0
  336. graph_crawler-5.3.4/graph_crawler/infrastructure/transport/connection_pool.py +349 -0
  337. graph_crawler-5.3.4/graph_crawler/infrastructure/transport/context.py +114 -0
  338. graph_crawler-5.3.4/graph_crawler/infrastructure/transport/core/__init__.py +15 -0
  339. graph_crawler-5.3.4/graph_crawler/infrastructure/transport/core/base_async.py +378 -0
  340. graph_crawler-5.3.4/graph_crawler/infrastructure/transport/core/body_decoder.py +26 -0
  341. graph_crawler-5.3.4/graph_crawler/infrastructure/transport/core/mixins.py +258 -0
  342. graph_crawler-5.3.4/graph_crawler/infrastructure/transport/core/redirect_utils.py +168 -0
  343. graph_crawler-5.3.4/graph_crawler/infrastructure/transport/escalation.py +996 -0
  344. graph_crawler-5.3.4/graph_crawler/infrastructure/transport/factory.py +210 -0
  345. graph_crawler-5.3.4/graph_crawler/infrastructure/transport/playwright/__init__.py +19 -0
  346. graph_crawler-5.3.4/graph_crawler/infrastructure/transport/playwright/adaptive_semaphore.py +65 -0
  347. graph_crawler-5.3.4/graph_crawler/infrastructure/transport/playwright/batch_scheduler.py +764 -0
  348. graph_crawler-5.3.4/graph_crawler/infrastructure/transport/playwright/browser_factory.py +580 -0
  349. graph_crawler-5.3.4/graph_crawler/infrastructure/transport/playwright/browser_profile.py +718 -0
  350. graph_crawler-5.3.4/graph_crawler/infrastructure/transport/playwright/config.py +84 -0
  351. graph_crawler-5.3.4/graph_crawler/infrastructure/transport/playwright/context.py +46 -0
  352. graph_crawler-5.3.4/graph_crawler/infrastructure/transport/playwright/driver.py +80 -0
  353. graph_crawler-5.3.4/graph_crawler/infrastructure/transport/playwright/engine.py +480 -0
  354. graph_crawler-5.3.4/graph_crawler/infrastructure/transport/playwright/fetch_metrics.py +115 -0
  355. graph_crawler-5.3.4/graph_crawler/infrastructure/transport/playwright/net/__init__.py +41 -0
  356. graph_crawler-5.3.4/graph_crawler/infrastructure/transport/playwright/net/geoip.py +136 -0
  357. graph_crawler-5.3.4/graph_crawler/infrastructure/transport/playwright/net/proxy_pool.py +225 -0
  358. graph_crawler-5.3.4/graph_crawler/infrastructure/transport/playwright/net/rate_limiter.py +139 -0
  359. graph_crawler-5.3.4/graph_crawler/infrastructure/transport/playwright/page_actions.py +186 -0
  360. graph_crawler-5.3.4/graph_crawler/infrastructure/transport/playwright/page_fetch.py +968 -0
  361. graph_crawler-5.3.4/graph_crawler/infrastructure/transport/playwright/plugins/__init__.py +71 -0
  362. graph_crawler-5.3.4/graph_crawler/infrastructure/transport/playwright/plugins/_network_record.py +66 -0
  363. graph_crawler-5.3.4/graph_crawler/infrastructure/transport/playwright/plugins/captcha_detector.py +315 -0
  364. graph_crawler-5.3.4/graph_crawler/infrastructure/transport/playwright/plugins/captcha_solver.py +108 -0
  365. graph_crawler-5.3.4/graph_crawler/infrastructure/transport/playwright/plugins/cookie_consent.py +565 -0
  366. graph_crawler-5.3.4/graph_crawler/infrastructure/transport/playwright/plugins/form_filler.py +177 -0
  367. graph_crawler-5.3.4/graph_crawler/infrastructure/transport/playwright/plugins/human_bezier.py +297 -0
  368. graph_crawler-5.3.4/graph_crawler/infrastructure/transport/playwright/plugins/network_log.py +406 -0
  369. graph_crawler-5.3.4/graph_crawler/infrastructure/transport/playwright/plugins/ram_adaptive.py +208 -0
  370. graph_crawler-5.3.4/graph_crawler/infrastructure/transport/playwright/plugins/screenshot.py +169 -0
  371. graph_crawler-5.3.4/graph_crawler/infrastructure/transport/playwright/plugins/user_profile.py +556 -0
  372. graph_crawler-5.3.4/graph_crawler/infrastructure/transport/playwright/pool_lifecycle.py +658 -0
  373. graph_crawler-5.3.4/graph_crawler/infrastructure/transport/playwright/pooled_driver.py +706 -0
  374. graph_crawler-5.3.4/graph_crawler/infrastructure/transport/playwright/stages.py +35 -0
  375. graph_crawler-5.3.4/graph_crawler/infrastructure/transport/playwright/stealth_hints.py +153 -0
  376. graph_crawler-5.3.4/graph_crawler/infrastructure/transport/plugin_manager.py +316 -0
  377. graph_crawler-5.3.4/graph_crawler/infrastructure/transport/protocols.py +132 -0
  378. graph_crawler-5.3.4/graph_crawler/infrastructure/transport/undetected/__init__.py +8 -0
  379. graph_crawler-5.3.4/graph_crawler/infrastructure/transport/undetected/async_driver.py +465 -0
  380. graph_crawler-5.3.4/graph_crawler/native/__init__.py +199 -0
  381. graph_crawler-5.3.4/graph_crawler/native/bloom_filter.pyx +255 -0
  382. graph_crawler-5.3.4/graph_crawler/native/html_parser.pyx +262 -0
  383. graph_crawler-5.3.4/graph_crawler/native/setup.py +103 -0
  384. graph_crawler-5.3.4/graph_crawler/native/url_utils.pyx +209 -0
  385. graph_crawler-5.3.4/graph_crawler/observability/__init__.py +62 -0
  386. graph_crawler-5.3.4/graph_crawler/observability/decorators/__init__.py +11 -0
  387. graph_crawler-5.3.4/graph_crawler/observability/decorators/cache.py +126 -0
  388. graph_crawler-5.3.4/graph_crawler/observability/decorators/log.py +56 -0
  389. graph_crawler-5.3.4/graph_crawler/observability/decorators/retry.py +121 -0
  390. graph_crawler-5.3.4/graph_crawler/observability/decorators/timing.py +43 -0
  391. graph_crawler-5.3.4/graph_crawler/observability/error_tracing.py +361 -0
  392. graph_crawler-5.3.4/graph_crawler/observability/extensions/__init__.py +18 -0
  393. graph_crawler-5.3.4/graph_crawler/observability/extensions/memory_guard.py +237 -0
  394. graph_crawler-5.3.4/graph_crawler/observability/extensions/state_manager.py +319 -0
  395. graph_crawler-5.3.4/graph_crawler/observability/listeners/__init__.py +33 -0
  396. graph_crawler-5.3.4/graph_crawler/observability/listeners/base.py +82 -0
  397. graph_crawler-5.3.4/graph_crawler/observability/listeners/base_metrics_listener.py +18 -0
  398. graph_crawler-5.3.4/graph_crawler/observability/listeners/crawl_listener.py +28 -0
  399. graph_crawler-5.3.4/graph_crawler/observability/listeners/dlq_listener.py +215 -0
  400. graph_crawler-5.3.4/graph_crawler/observability/listeners/error_listener.py +18 -0
  401. graph_crawler-5.3.4/graph_crawler/observability/listeners/logging_listener.py +88 -0
  402. graph_crawler-5.3.4/graph_crawler/observability/listeners/metrics_listener.py +109 -0
  403. graph_crawler-5.3.4/graph_crawler/observability/listeners/node_listener.py +33 -0
  404. graph_crawler-5.3.4/graph_crawler/observability/listeners/plugin_listener.py +28 -0
  405. graph_crawler-5.3.4/graph_crawler/observability/listeners/storage_listener.py +21 -0
  406. graph_crawler-5.3.4/graph_crawler/observability/listeners/url_listener.py +29 -0
  407. graph_crawler-5.3.4/graph_crawler/observability/metrics/__init__.py +23 -0
  408. graph_crawler-5.3.4/graph_crawler/observability/metrics/memory_profiler.py +508 -0
  409. graph_crawler-5.3.4/graph_crawler/observability/metrics/metrics_collector.py +408 -0
  410. graph_crawler-5.3.4/graph_crawler/observability/metrics/prometheus_metrics.py +293 -0
  411. graph_crawler-5.3.4/graph_crawler/observability/metrics_core.py +389 -0
  412. graph_crawler-5.3.4/graph_crawler/observability/structured_logging.py +216 -0
  413. graph_crawler-5.3.4/graph_crawler/observability/tracing.py +291 -0
  414. graph_crawler-5.3.4/graph_crawler/optimizations/__init__.py +89 -0
  415. graph_crawler-5.3.4/graph_crawler/optimizations/generators.py +477 -0
  416. graph_crawler-5.3.4/graph_crawler/optimizations/memory_slots.py +641 -0
  417. graph_crawler-5.3.4/graph_crawler/optimizations/simhash_numba.py +284 -0
  418. graph_crawler-5.3.4/graph_crawler/shared/__init__.py +25 -0
  419. graph_crawler-5.3.4/graph_crawler/shared/constants.py +943 -0
  420. graph_crawler-5.3.4/graph_crawler/shared/dto/__init__.py +38 -0
  421. graph_crawler-5.3.4/graph_crawler/shared/dto/edge_dto.py +52 -0
  422. graph_crawler-5.3.4/graph_crawler/shared/dto/graph_dto.py +97 -0
  423. graph_crawler-5.3.4/graph_crawler/shared/dto/node_dto.py +193 -0
  424. graph_crawler-5.3.4/graph_crawler/shared/error_handling/__init__.py +15 -0
  425. graph_crawler-5.3.4/graph_crawler/shared/error_handling/error_handler.py +333 -0
  426. graph_crawler-5.3.4/graph_crawler/shared/exceptions.py +394 -0
  427. graph_crawler-5.3.4/graph_crawler/shared/platform/__init__.py +125 -0
  428. graph_crawler-5.3.4/graph_crawler/shared/platform/adaptive_resolver.py +414 -0
  429. graph_crawler-5.3.4/graph_crawler/shared/platform/config.py +635 -0
  430. graph_crawler-5.3.4/graph_crawler/shared/platform/detector.py +334 -0
  431. graph_crawler-5.3.4/graph_crawler/shared/platform/diagnostics.py +660 -0
  432. graph_crawler-5.3.4/graph_crawler/shared/platform/metrics.py +299 -0
  433. graph_crawler-5.3.4/graph_crawler/shared/security/__init__.py +22 -0
  434. graph_crawler-5.3.4/graph_crawler/shared/security/url_sanitizer.py +100 -0
  435. graph_crawler-5.3.4/graph_crawler/shared/security/url_validator.py +299 -0
  436. graph_crawler-5.3.4/graph_crawler/shared/utils/__init__.py +212 -0
  437. graph_crawler-5.3.4/graph_crawler/shared/utils/async_compat.py +140 -0
  438. graph_crawler-5.3.4/graph_crawler/shared/utils/bloom_filter.py +373 -0
  439. graph_crawler-5.3.4/graph_crawler/shared/utils/captcha/__init__.py +36 -0
  440. graph_crawler-5.3.4/graph_crawler/shared/utils/captcha/base.py +92 -0
  441. graph_crawler-5.3.4/graph_crawler/shared/utils/captcha/manager.py +474 -0
  442. graph_crawler-5.3.4/graph_crawler/shared/utils/celery_config.py +332 -0
  443. graph_crawler-5.3.4/graph_crawler/shared/utils/celery_helpers.py +153 -0
  444. graph_crawler-5.3.4/graph_crawler/shared/utils/cgroup_limits.py +227 -0
  445. graph_crawler-5.3.4/graph_crawler/shared/utils/content_decoder.py +150 -0
  446. graph_crawler-5.3.4/graph_crawler/shared/utils/distributed_rate_limiter.py +265 -0
  447. graph_crawler-5.3.4/graph_crawler/shared/utils/distributed_rate_limiter_backends.py +284 -0
  448. graph_crawler-5.3.4/graph_crawler/shared/utils/dns_cache.py +370 -0
  449. graph_crawler-5.3.4/graph_crawler/shared/utils/enterprise_ua_generator.py +294 -0
  450. graph_crawler-5.3.4/graph_crawler/shared/utils/event_publisher_mixin.py +187 -0
  451. graph_crawler-5.3.4/graph_crawler/shared/utils/fast_json.py +240 -0
  452. graph_crawler-5.3.4/graph_crawler/shared/utils/fingerprint.py +36 -0
  453. graph_crawler-5.3.4/graph_crawler/shared/utils/fingerprint_data.py +99 -0
  454. graph_crawler-5.3.4/graph_crawler/shared/utils/fingerprint_generators.py +128 -0
  455. graph_crawler-5.3.4/graph_crawler/shared/utils/fingerprint_profile.py +121 -0
  456. graph_crawler-5.3.4/graph_crawler/shared/utils/fingerprint_stealth.py +105 -0
  457. graph_crawler-5.3.4/graph_crawler/shared/utils/html_utils.py +118 -0
  458. graph_crawler-5.3.4/graph_crawler/shared/utils/id_generator.py +195 -0
  459. graph_crawler-5.3.4/graph_crawler/shared/utils/isolated_executor.py +200 -0
  460. graph_crawler-5.3.4/graph_crawler/shared/utils/memory_optimizer.py +536 -0
  461. graph_crawler-5.3.4/graph_crawler/shared/utils/rate_limiter.py +185 -0
  462. graph_crawler-5.3.4/graph_crawler/shared/utils/regex_validator.py +966 -0
  463. graph_crawler-5.3.4/graph_crawler/shared/utils/shadow_dom.py +36 -0
  464. graph_crawler-5.3.4/graph_crawler/shared/utils/text_utils.py +387 -0
  465. graph_crawler-5.3.4/graph_crawler/shared/utils/url_patterns.py +135 -0
  466. graph_crawler-5.3.4/graph_crawler/shared/utils/url_utils.py +595 -0
  467. graph_crawler-5.3.4/graph_crawler/shared/utils/user_agent_rotator.py +333 -0
  468. graph_crawler-5.3.4/graph_crawler/shared/utils/validation_helpers.py +225 -0
  469. graph_crawler-5.3.4/graph_crawler/shared/utils/visualization.py +134 -0
  470. graph_crawler-5.3.4/graph_crawler/shared/utils/visualization_core.py +566 -0
  471. graph_crawler-5.3.4/graph_crawler/tools/__init__.py +1 -0
  472. graph_crawler-5.3.4/graph_crawler/tools/db_cleanup.py +263 -0
  473. graph_crawler-5.3.4/graph_crawler.egg-info/PKG-INFO +522 -0
  474. graph_crawler-5.3.4/graph_crawler.egg-info/SOURCES.txt +479 -0
  475. graph_crawler-5.3.4/pyproject.toml +301 -0
  476. graph_crawler-5.3.4/setup.cfg +4 -0
  477. graph_crawler-5.3.2/CHANGELOG.md +0 -353
  478. graph_crawler-5.3.2/CODE_STYLE.md +0 -1473
  479. graph_crawler-5.3.2/LICENSE +0 -21
  480. graph_crawler-5.3.2/MANIFEST.in +0 -16
  481. graph_crawler-5.3.2/PKG-INFO +0 -531
  482. graph_crawler-5.3.2/README.md +0 -410
  483. graph_crawler-5.3.2/graph_crawler/__init__.py +0 -492
  484. graph_crawler-5.3.2/graph_crawler/__version__.py +0 -8
  485. graph_crawler-5.3.2/graph_crawler/ai/__init__.py +0 -50
  486. graph_crawler-5.3.2/graph_crawler/api/__init__.py +0 -28
  487. graph_crawler-5.3.2/graph_crawler/api/_core.py +0 -283
  488. graph_crawler-5.3.2/graph_crawler/api/_distributed.py +0 -172
  489. graph_crawler-5.3.2/graph_crawler/api/_shared.py +0 -110
  490. graph_crawler-5.3.2/graph_crawler/api/_sitemap_distributed.py +0 -238
  491. graph_crawler-5.3.2/graph_crawler/api/async_.py +0 -323
  492. graph_crawler-5.3.2/graph_crawler/api/cli.py +0 -440
  493. graph_crawler-5.3.2/graph_crawler/api/client/__init__.py +0 -8
  494. graph_crawler-5.3.2/graph_crawler/api/client/client.py +0 -470
  495. graph_crawler-5.3.2/graph_crawler/api/history_manager.py +0 -55
  496. graph_crawler-5.3.2/graph_crawler/api/project_init.py +0 -196
  497. graph_crawler-5.3.2/graph_crawler/api/server/__init__.py +0 -18
  498. graph_crawler-5.3.2/graph_crawler/api/server/crawl_monitor.py +0 -145
  499. graph_crawler-5.3.2/graph_crawler/api/server/dashboard.py +0 -221
  500. graph_crawler-5.3.2/graph_crawler/api/server/rest_api.py +0 -704
  501. graph_crawler-5.3.2/graph_crawler/api/server/webhooks.py +0 -421
  502. graph_crawler-5.3.2/graph_crawler/api/server/websocket_manager.py +0 -89
  503. graph_crawler-5.3.2/graph_crawler/api/stats_collector.py +0 -88
  504. graph_crawler-5.3.2/graph_crawler/api/sync.py +0 -536
  505. graph_crawler-5.3.2/graph_crawler/application/__init__.py +0 -38
  506. graph_crawler-5.3.2/graph_crawler/application/bootstrap.py +0 -211
  507. graph_crawler-5.3.2/graph_crawler/application/context/__init__.py +0 -31
  508. graph_crawler-5.3.2/graph_crawler/application/context/dependency_registry.py +0 -354
  509. graph_crawler-5.3.2/graph_crawler/application/context/graph_context.py +0 -217
  510. graph_crawler-5.3.2/graph_crawler/application/context/merge_context.py +0 -221
  511. graph_crawler-5.3.2/graph_crawler/application/dto/__init__.py +0 -67
  512. graph_crawler-5.3.2/graph_crawler/application/dto/edge_dto.py +0 -25
  513. graph_crawler-5.3.2/graph_crawler/application/dto/graph_dto.py +0 -27
  514. graph_crawler-5.3.2/graph_crawler/application/dto/mappers/__init__.py +0 -14
  515. graph_crawler-5.3.2/graph_crawler/application/dto/mappers/edge_mapper.py +0 -149
  516. graph_crawler-5.3.2/graph_crawler/application/dto/mappers/graph_mapper.py +0 -622
  517. graph_crawler-5.3.2/graph_crawler/application/dto/mappers/node_data_codec.py +0 -190
  518. graph_crawler-5.3.2/graph_crawler/application/dto/mappers/node_mapper.py +0 -417
  519. graph_crawler-5.3.2/graph_crawler/application/dto/node_dto.py +0 -27
  520. graph_crawler-5.3.2/graph_crawler/application/dto/utils.py +0 -272
  521. graph_crawler-5.3.2/graph_crawler/application/services/__init__.py +0 -60
  522. graph_crawler-5.3.2/graph_crawler/application/services/application_container.py +0 -208
  523. graph_crawler-5.3.2/graph_crawler/application/services/driver_factory.py +0 -147
  524. graph_crawler-5.3.2/graph_crawler/application/services/exporters/__init__.py +0 -26
  525. graph_crawler-5.3.2/graph_crawler/application/services/exporters/base_exporter.py +0 -150
  526. graph_crawler-5.3.2/graph_crawler/application/services/exporters/csv_exporter.py +0 -318
  527. graph_crawler-5.3.2/graph_crawler/application/services/exporters/edge_exporter.py +0 -432
  528. graph_crawler-5.3.2/graph_crawler/application/services/exporters/excel_exporter.py +0 -301
  529. graph_crawler-5.3.2/graph_crawler/application/services/exporters/jsonl_exporter.py +0 -290
  530. graph_crawler-5.3.2/graph_crawler/application/services/exporters/node_exporter.py +0 -284
  531. graph_crawler-5.3.2/graph_crawler/application/services/exporters/parquet_exporter.py +0 -248
  532. graph_crawler-5.3.2/graph_crawler/application/services/exporters/sql_exporter.py +0 -267
  533. graph_crawler-5.3.2/graph_crawler/application/services/finalize.py +0 -115
  534. graph_crawler-5.3.2/graph_crawler/application/services/low_memory_graph_saver.py +0 -337
  535. graph_crawler-5.3.2/graph_crawler/application/services/resource_budget.py +0 -179
  536. graph_crawler-5.3.2/graph_crawler/application/services/scheduling/__init__.py +0 -12
  537. graph_crawler-5.3.2/graph_crawler/application/services/scheduling/rule_based_scheduler.py +0 -113
  538. graph_crawler-5.3.2/graph_crawler/application/services/storage_factory.py +0 -195
  539. graph_crawler-5.3.2/graph_crawler/application/use_cases/__init__.py +0 -11
  540. graph_crawler-5.3.2/graph_crawler/application/use_cases/crawling/__init__.py +0 -81
  541. graph_crawler-5.3.2/graph_crawler/application/use_cases/crawling/adaptive_throttler.py +0 -373
  542. graph_crawler-5.3.2/graph_crawler/application/use_cases/crawling/async_bridge.py +0 -45
  543. graph_crawler-5.3.2/graph_crawler/application/use_cases/crawling/base_spider.py +0 -155
  544. graph_crawler-5.3.2/graph_crawler/application/use_cases/crawling/celery_batch_spider.py +0 -656
  545. graph_crawler-5.3.2/graph_crawler/application/use_cases/crawling/celery_spider.py +0 -445
  546. graph_crawler-5.3.2/graph_crawler/application/use_cases/crawling/checkpoint.py +0 -421
  547. graph_crawler-5.3.2/graph_crawler/application/use_cases/crawling/crawl_coordinator.py +0 -1049
  548. graph_crawler-5.3.2/graph_crawler/application/use_cases/crawling/dead_letter_queue.py +0 -413
  549. graph_crawler-5.3.2/graph_crawler/application/use_cases/crawling/domain_rate_limiter.py +0 -262
  550. graph_crawler-5.3.2/graph_crawler/application/use_cases/crawling/filters/__init__.py +0 -10
  551. graph_crawler-5.3.2/graph_crawler/application/use_cases/crawling/filters/base.py +0 -74
  552. graph_crawler-5.3.2/graph_crawler/application/use_cases/crawling/filters/domain_filter.py +0 -195
  553. graph_crawler-5.3.2/graph_crawler/application/use_cases/crawling/filters/domain_patterns.py +0 -30
  554. graph_crawler-5.3.2/graph_crawler/application/use_cases/crawling/filters/path_filter.py +0 -95
  555. graph_crawler-5.3.2/graph_crawler/application/use_cases/crawling/incremental_strategy.py +0 -239
  556. graph_crawler-5.3.2/graph_crawler/application/use_cases/crawling/link_processor.py +0 -932
  557. graph_crawler-5.3.2/graph_crawler/application/use_cases/crawling/multiprocess_spider.py +0 -511
  558. graph_crawler-5.3.2/graph_crawler/application/use_cases/crawling/node_scanner.py +0 -866
  559. graph_crawler-5.3.2/graph_crawler/application/use_cases/crawling/parsers/__init__.py +0 -6
  560. graph_crawler-5.3.2/graph_crawler/application/use_cases/crawling/parsers/base.py +0 -73
  561. graph_crawler-5.3.2/graph_crawler/application/use_cases/crawling/parsers/html_parser.py +0 -154
  562. graph_crawler-5.3.2/graph_crawler/application/use_cases/crawling/progress_tracker.py +0 -235
  563. graph_crawler-5.3.2/graph_crawler/application/use_cases/crawling/scheduler.py +0 -747
  564. graph_crawler-5.3.2/graph_crawler/application/use_cases/crawling/serialization_mixin.py +0 -218
  565. graph_crawler-5.3.2/graph_crawler/application/use_cases/crawling/sitemap_parser.py +0 -657
  566. graph_crawler-5.3.2/graph_crawler/application/use_cases/crawling/sitemap_processor.py +0 -401
  567. graph_crawler-5.3.2/graph_crawler/application/use_cases/crawling/sitemap_spider.py +0 -608
  568. graph_crawler-5.3.2/graph_crawler/application/use_cases/crawling/spider.py +0 -813
  569. graph_crawler-5.3.2/graph_crawler/application/use_cases/crawling/spider_lifecycle.py +0 -108
  570. graph_crawler-5.3.2/graph_crawler/application/use_cases/crawling/worker_pool.py +0 -154
  571. graph_crawler-5.3.2/graph_crawler/application/use_cases/graph_export.py +0 -504
  572. graph_crawler-5.3.2/graph_crawler/application/use_cases/graph_merge/__init__.py +0 -33
  573. graph_crawler-5.3.2/graph_crawler/application/use_cases/graph_merge/graph_operations.py +0 -632
  574. graph_crawler-5.3.2/graph_crawler/application/use_cases/graph_merge/merge_strategies.py +0 -348
  575. graph_crawler-5.3.2/graph_crawler/data/__init__.py +0 -28
  576. graph_crawler-5.3.2/graph_crawler/data/backends/__init__.py +0 -21
  577. graph_crawler-5.3.2/graph_crawler/data/backends/memory.py +0 -486
  578. graph_crawler-5.3.2/graph_crawler/data/backends/sqlite.py +0 -1866
  579. graph_crawler-5.3.2/graph_crawler/data/interfaces.py +0 -563
  580. graph_crawler-5.3.2/graph_crawler/domain/__init__.py +0 -62
  581. graph_crawler-5.3.2/graph_crawler/domain/context/__init__.py +0 -14
  582. graph_crawler-5.3.2/graph_crawler/domain/context/crawl_context.py +0 -531
  583. graph_crawler-5.3.2/graph_crawler/domain/entities/__init__.py +0 -32
  584. graph_crawler-5.3.2/graph_crawler/domain/entities/edge.py +0 -345
  585. graph_crawler-5.3.2/graph_crawler/domain/entities/edge_analysis.py +0 -223
  586. graph_crawler-5.3.2/graph_crawler/domain/entities/graph.py +0 -4169
  587. graph_crawler-5.3.2/graph_crawler/domain/entities/graph_operations.py +0 -30
  588. graph_crawler-5.3.2/graph_crawler/domain/entities/graph_statistics.py +0 -10
  589. graph_crawler-5.3.2/graph_crawler/domain/entities/merge_strategies.py +0 -33
  590. graph_crawler-5.3.2/graph_crawler/domain/entities/node.py +0 -780
  591. graph_crawler-5.3.2/graph_crawler/domain/entities/redirect_mode.py +0 -23
  592. graph_crawler-5.3.2/graph_crawler/domain/entities/registries.py +0 -223
  593. graph_crawler-5.3.2/graph_crawler/domain/entities/sitemap_node.py +0 -74
  594. graph_crawler-5.3.2/graph_crawler/domain/entities/strategies.py +0 -202
  595. graph_crawler-5.3.2/graph_crawler/domain/events/__init__.py +0 -162
  596. graph_crawler-5.3.2/graph_crawler/domain/events/base.py +0 -60
  597. graph_crawler-5.3.2/graph_crawler/domain/events/crawl.py +0 -112
  598. graph_crawler-5.3.2/graph_crawler/domain/events/edge.py +0 -43
  599. graph_crawler-5.3.2/graph_crawler/domain/events/event_bus.py +0 -250
  600. graph_crawler-5.3.2/graph_crawler/domain/events/events.py +0 -313
  601. graph_crawler-5.3.2/graph_crawler/domain/events/fetch.py +0 -120
  602. graph_crawler-5.3.2/graph_crawler/domain/events/idempotent_subscriber.py +0 -120
  603. graph_crawler-5.3.2/graph_crawler/domain/events/legacy_type_map.py +0 -45
  604. graph_crawler-5.3.2/graph_crawler/domain/events/llm.py +0 -148
  605. graph_crawler-5.3.2/graph_crawler/domain/events/node.py +0 -111
  606. graph_crawler-5.3.2/graph_crawler/domain/events/plugin.py +0 -92
  607. graph_crawler-5.3.2/graph_crawler/domain/events/scheduler.py +0 -98
  608. graph_crawler-5.3.2/graph_crawler/domain/events/storage.py +0 -161
  609. graph_crawler-5.3.2/graph_crawler/domain/interfaces/__init__.py +0 -111
  610. graph_crawler-5.3.2/graph_crawler/domain/interfaces/adapter.py +0 -29
  611. graph_crawler-5.3.2/graph_crawler/domain/interfaces/control_channel.py +0 -371
  612. graph_crawler-5.3.2/graph_crawler/domain/interfaces/crawl_context.py +0 -49
  613. graph_crawler-5.3.2/graph_crawler/domain/interfaces/distributed_spider.py +0 -62
  614. graph_crawler-5.3.2/graph_crawler/domain/interfaces/driver.py +0 -87
  615. graph_crawler-5.3.2/graph_crawler/domain/interfaces/event_bus.py +0 -61
  616. graph_crawler-5.3.2/graph_crawler/domain/interfaces/exporters.py +0 -69
  617. graph_crawler-5.3.2/graph_crawler/domain/interfaces/filter.py +0 -19
  618. graph_crawler-5.3.2/graph_crawler/domain/interfaces/merge_context.py +0 -52
  619. graph_crawler-5.3.2/graph_crawler/domain/interfaces/node_interfaces.py +0 -389
  620. graph_crawler-5.3.2/graph_crawler/domain/interfaces/parser.py +0 -88
  621. graph_crawler-5.3.2/graph_crawler/domain/interfaces/plugin_manager.py +0 -53
  622. graph_crawler-5.3.2/graph_crawler/domain/interfaces/processor.py +0 -11
  623. graph_crawler-5.3.2/graph_crawler/domain/interfaces/scanner.py +0 -57
  624. graph_crawler-5.3.2/graph_crawler/domain/interfaces/scheduler.py +0 -43
  625. graph_crawler-5.3.2/graph_crawler/domain/interfaces/scheduling/__init__.py +0 -40
  626. graph_crawler-5.3.2/graph_crawler/domain/interfaces/scheduling/frontier.py +0 -97
  627. graph_crawler-5.3.2/graph_crawler/domain/interfaces/scheduling/scheduler.py +0 -107
  628. graph_crawler-5.3.2/graph_crawler/domain/interfaces/spider.py +0 -63
  629. graph_crawler-5.3.2/graph_crawler/domain/interfaces/stop_condition.py +0 -211
  630. graph_crawler-5.3.2/graph_crawler/domain/interfaces/storage/__init__.py +0 -43
  631. graph_crawler-5.3.2/graph_crawler/domain/interfaces/storage/base.py +0 -68
  632. graph_crawler-5.3.2/graph_crawler/domain/interfaces/storage/eviction.py +0 -98
  633. graph_crawler-5.3.2/graph_crawler/domain/interfaces/storage/queue.py +0 -234
  634. graph_crawler-5.3.2/graph_crawler/domain/services/__init__.py +0 -216
  635. graph_crawler-5.3.2/graph_crawler/domain/services/adjacency_maintenance.py +0 -95
  636. graph_crawler-5.3.2/graph_crawler/domain/services/cycle_detection.py +0 -92
  637. graph_crawler-5.3.2/graph_crawler/domain/services/degree_ranking.py +0 -47
  638. graph_crawler-5.3.2/graph_crawler/domain/services/depth_context.py +0 -123
  639. graph_crawler-5.3.2/graph_crawler/domain/services/display_title.py +0 -47
  640. graph_crawler-5.3.2/graph_crawler/domain/services/duplicate_detection.py +0 -141
  641. graph_crawler-5.3.2/graph_crawler/domain/services/duplicate_selector.py +0 -127
  642. graph_crawler-5.3.2/graph_crawler/domain/services/duplicate_stats.py +0 -63
  643. graph_crawler-5.3.2/graph_crawler/domain/services/edge_filter.py +0 -82
  644. graph_crawler-5.3.2/graph_crawler/domain/services/edge_statistics.py +0 -110
  645. graph_crawler-5.3.2/graph_crawler/domain/services/eviction_policy.py +0 -83
  646. graph_crawler-5.3.2/graph_crawler/domain/services/graph_query_cascade.py +0 -178
  647. graph_crawler-5.3.2/graph_crawler/domain/services/graph_statistics.py +0 -186
  648. graph_crawler-5.3.2/graph_crawler/domain/services/graph_traversal.py +0 -150
  649. graph_crawler-5.3.2/graph_crawler/domain/services/language_versions.py +0 -73
  650. graph_crawler-5.3.2/graph_crawler/domain/services/lsh_index.py +0 -99
  651. graph_crawler-5.3.2/graph_crawler/domain/services/minimap_builder.py +0 -147
  652. graph_crawler-5.3.2/graph_crawler/domain/services/node_content_resolver.py +0 -128
  653. graph_crawler-5.3.2/graph_crawler/domain/services/node_view_builder.py +0 -163
  654. graph_crawler-5.3.2/graph_crawler/domain/services/pagination_guards.py +0 -136
  655. graph_crawler-5.3.2/graph_crawler/domain/services/predicate_ops.py +0 -77
  656. graph_crawler-5.3.2/graph_crawler/domain/services/schema_filter.py +0 -138
  657. graph_crawler-5.3.2/graph_crawler/domain/services/search_haystack.py +0 -102
  658. graph_crawler-5.3.2/graph_crawler/domain/services/simhash_clustering.py +0 -96
  659. graph_crawler-5.3.2/graph_crawler/domain/services/simhash_fallback.py +0 -59
  660. graph_crawler-5.3.2/graph_crawler/domain/services/similarity_ranking.py +0 -62
  661. graph_crawler-5.3.2/graph_crawler/domain/services/text_search.py +0 -157
  662. graph_crawler-5.3.2/graph_crawler/domain/services/url_clustering.py +0 -88
  663. graph_crawler-5.3.2/graph_crawler/domain/services/url_deduplication.py +0 -101
  664. graph_crawler-5.3.2/graph_crawler/domain/services/url_normalizer.py +0 -117
  665. graph_crawler-5.3.2/graph_crawler/domain/services/url_rule_matcher.py +0 -103
  666. graph_crawler-5.3.2/graph_crawler/domain/services/url_tree_builder.py +0 -197
  667. graph_crawler-5.3.2/graph_crawler/domain/value_objects/__init__.py +0 -88
  668. graph_crawler-5.3.2/graph_crawler/domain/value_objects/configs.py +0 -884
  669. graph_crawler-5.3.2/graph_crawler/domain/value_objects/domain_patterns.py +0 -71
  670. graph_crawler-5.3.2/graph_crawler/domain/value_objects/fetch_options.py +0 -57
  671. graph_crawler-5.3.2/graph_crawler/domain/value_objects/html_document.py +0 -59
  672. graph_crawler-5.3.2/graph_crawler/domain/value_objects/lifecycle.py +0 -30
  673. graph_crawler-5.3.2/graph_crawler/domain/value_objects/models.py +0 -1315
  674. graph_crawler-5.3.2/graph_crawler/domain/value_objects/page_actions.py +0 -72
  675. graph_crawler-5.3.2/graph_crawler/domain/value_objects/redirect_hop.py +0 -49
  676. graph_crawler-5.3.2/graph_crawler/domain/value_objects/scheduling/__init__.py +0 -23
  677. graph_crawler-5.3.2/graph_crawler/domain/value_objects/scheduling/crawl_request.py +0 -153
  678. graph_crawler-5.3.2/graph_crawler/domain/value_objects/scheduling/retry_policy.py +0 -109
  679. graph_crawler-5.3.2/graph_crawler/domain/value_objects/settings.py +0 -350
  680. graph_crawler-5.3.2/graph_crawler/domain/value_objects/url_normalization.py +0 -497
  681. graph_crawler-5.3.2/graph_crawler/domain/value_objects/views.py +0 -293
  682. graph_crawler-5.3.2/graph_crawler/extensions/__init__.py +0 -1
  683. graph_crawler-5.3.2/graph_crawler/extensions/middleware/__init__.py +0 -65
  684. graph_crawler-5.3.2/graph_crawler/extensions/middleware/base.py +0 -136
  685. graph_crawler-5.3.2/graph_crawler/extensions/middleware/cache_middleware.py +0 -277
  686. graph_crawler-5.3.2/graph_crawler/extensions/middleware/chain.py +0 -155
  687. graph_crawler-5.3.2/graph_crawler/extensions/middleware/error_recovery_middleware.py +0 -442
  688. graph_crawler-5.3.2/graph_crawler/extensions/middleware/logging_middleware.py +0 -108
  689. graph_crawler-5.3.2/graph_crawler/extensions/middleware/proxy_health.py +0 -141
  690. graph_crawler-5.3.2/graph_crawler/extensions/middleware/proxy_middleware.py +0 -209
  691. graph_crawler-5.3.2/graph_crawler/extensions/middleware/proxy_models.py +0 -80
  692. graph_crawler-5.3.2/graph_crawler/extensions/middleware/proxy_selection.py +0 -87
  693. graph_crawler-5.3.2/graph_crawler/extensions/middleware/rate_limit_middleware.py +0 -262
  694. graph_crawler-5.3.2/graph_crawler/extensions/middleware/request_response_middleware.py +0 -476
  695. graph_crawler-5.3.2/graph_crawler/extensions/middleware/retry_middleware.py +0 -279
  696. graph_crawler-5.3.2/graph_crawler/extensions/middleware/robots_cache.py +0 -85
  697. graph_crawler-5.3.2/graph_crawler/extensions/middleware/robots_middleware.py +0 -110
  698. graph_crawler-5.3.2/graph_crawler/extensions/middleware/robots_validator.py +0 -60
  699. graph_crawler-5.3.2/graph_crawler/extensions/middleware/user_agent_middleware.py +0 -251
  700. graph_crawler-5.3.2/graph_crawler/extensions/plugins/__init__.py +0 -57
  701. graph_crawler-5.3.2/graph_crawler/extensions/plugins/builtin/__init__.py +0 -7
  702. graph_crawler-5.3.2/graph_crawler/extensions/plugins/builtin/stats_export_plugin.py +0 -99
  703. graph_crawler-5.3.2/graph_crawler/extensions/plugins/crawl_engine/__init__.py +0 -24
  704. graph_crawler-5.3.2/graph_crawler/extensions/plugins/crawl_engine/base.py +0 -155
  705. graph_crawler-5.3.2/graph_crawler/extensions/plugins/crawl_engine/priority_provider.py +0 -247
  706. graph_crawler-5.3.2/graph_crawler/extensions/plugins/crawl_engine/smart_crawl.py +0 -296
  707. graph_crawler-5.3.2/graph_crawler/extensions/plugins/engine/__init__.py +0 -128
  708. graph_crawler-5.3.2/graph_crawler/extensions/plugins/engine/anti_bot_detection.py +0 -55
  709. graph_crawler-5.3.2/graph_crawler/extensions/plugins/engine/anti_bot_playwright.py +0 -88
  710. graph_crawler-5.3.2/graph_crawler/extensions/plugins/engine/anti_bot_scripts.py +0 -136
  711. graph_crawler-5.3.2/graph_crawler/extensions/plugins/engine/anti_bot_stealth.py +0 -177
  712. graph_crawler-5.3.2/graph_crawler/extensions/plugins/engine/base.py +0 -121
  713. graph_crawler-5.3.2/graph_crawler/extensions/plugins/engine/captcha/__init__.py +0 -22
  714. graph_crawler-5.3.2/graph_crawler/extensions/plugins/engine/captcha/detector.py +0 -94
  715. graph_crawler-5.3.2/graph_crawler/extensions/plugins/engine/captcha/models.py +0 -74
  716. graph_crawler-5.3.2/graph_crawler/extensions/plugins/engine/captcha/plugin.py +0 -228
  717. graph_crawler-5.3.2/graph_crawler/extensions/plugins/engine/captcha/services.py +0 -389
  718. graph_crawler-5.3.2/graph_crawler/extensions/plugins/node/__init__.py +0 -86
  719. graph_crawler-5.3.2/graph_crawler/extensions/plugins/node/base.py +0 -520
  720. graph_crawler-5.3.2/graph_crawler/extensions/plugins/node/content_extractors/__init__.py +0 -15
  721. graph_crawler-5.3.2/graph_crawler/extensions/plugins/node/content_extractors/base.py +0 -82
  722. graph_crawler-5.3.2/graph_crawler/extensions/plugins/node/content_extractors/goose3_extractor.py +0 -80
  723. graph_crawler-5.3.2/graph_crawler/extensions/plugins/node/content_extractors/newspaper_extractor.py +0 -93
  724. graph_crawler-5.3.2/graph_crawler/extensions/plugins/node/content_extractors/plugin.py +0 -132
  725. graph_crawler-5.3.2/graph_crawler/extensions/plugins/node/content_extractors/readability_extractor.py +0 -91
  726. graph_crawler-5.3.2/graph_crawler/extensions/plugins/node/defaults.py +0 -32
  727. graph_crawler-5.3.2/graph_crawler/extensions/plugins/node/extractors/__init__.py +0 -30
  728. graph_crawler-5.3.2/graph_crawler/extensions/plugins/node/extractors/email_extractor.py +0 -146
  729. graph_crawler-5.3.2/graph_crawler/extensions/plugins/node/extractors/phone_extractor.py +0 -136
  730. graph_crawler-5.3.2/graph_crawler/extensions/plugins/node/extractors/price_extractor.py +0 -137
  731. graph_crawler-5.3.2/graph_crawler/extensions/plugins/node/links.py +0 -184
  732. graph_crawler-5.3.2/graph_crawler/extensions/plugins/node/markdown_plugin.py +0 -249
  733. graph_crawler-5.3.2/graph_crawler/extensions/plugins/node/metadata.py +0 -384
  734. graph_crawler-5.3.2/graph_crawler/extensions/plugins/node/smart_page_finder.py +0 -749
  735. graph_crawler-5.3.2/graph_crawler/extensions/plugins/node/structured_data/__init__.py +0 -51
  736. graph_crawler-5.3.2/graph_crawler/extensions/plugins/node/structured_data/constants.py +0 -27
  737. graph_crawler-5.3.2/graph_crawler/extensions/plugins/node/structured_data/exceptions.py +0 -18
  738. graph_crawler-5.3.2/graph_crawler/extensions/plugins/node/structured_data/extractor.py +0 -361
  739. graph_crawler-5.3.2/graph_crawler/extensions/plugins/node/structured_data/options.py +0 -62
  740. graph_crawler-5.3.2/graph_crawler/extensions/plugins/node/structured_data/parsers/__init__.py +0 -25
  741. graph_crawler-5.3.2/graph_crawler/extensions/plugins/node/structured_data/parsers/base.py +0 -43
  742. graph_crawler-5.3.2/graph_crawler/extensions/plugins/node/structured_data/parsers/jsonld.py +0 -331
  743. graph_crawler-5.3.2/graph_crawler/extensions/plugins/node/structured_data/parsers/microdata.py +0 -117
  744. graph_crawler-5.3.2/graph_crawler/extensions/plugins/node/structured_data/parsers/opengraph.py +0 -66
  745. graph_crawler-5.3.2/graph_crawler/extensions/plugins/node/structured_data/parsers/rdfa.py +0 -122
  746. graph_crawler-5.3.2/graph_crawler/extensions/plugins/node/structured_data/parsers/twitter.py +0 -66
  747. graph_crawler-5.3.2/graph_crawler/extensions/plugins/node/structured_data/plugin.py +0 -132
  748. graph_crawler-5.3.2/graph_crawler/extensions/plugins/node/structured_data/result.py +0 -233
  749. graph_crawler-5.3.2/graph_crawler/extensions/plugins/node/text.py +0 -76
  750. graph_crawler-5.3.2/graph_crawler/extensions/plugins/node/url_normalizer.py +0 -363
  751. graph_crawler-5.3.2/graph_crawler/extensions/plugins/registry.py +0 -97
  752. graph_crawler-5.3.2/graph_crawler/infrastructure/__init__.py +0 -1
  753. graph_crawler-5.3.2/graph_crawler/infrastructure/adapters/__init__.py +0 -60
  754. graph_crawler-5.3.2/graph_crawler/infrastructure/adapters/base.py +0 -498
  755. graph_crawler-5.3.2/graph_crawler/infrastructure/adapters/selectolax_adapter.py +0 -233
  756. graph_crawler-5.3.2/graph_crawler/infrastructure/messaging/__init__.py +0 -37
  757. graph_crawler-5.3.2/graph_crawler/infrastructure/messaging/celery_app.py +0 -202
  758. graph_crawler-5.3.2/graph_crawler/infrastructure/messaging/celery_batch.py +0 -284
  759. graph_crawler-5.3.2/graph_crawler/infrastructure/messaging/celery_job_task.py +0 -415
  760. graph_crawler-5.3.2/graph_crawler/infrastructure/messaging/celery_unified.py +0 -419
  761. graph_crawler-5.3.2/graph_crawler/infrastructure/messaging/config.py +0 -201
  762. graph_crawler-5.3.2/graph_crawler/infrastructure/messaging/easy_crawler.py +0 -279
  763. graph_crawler-5.3.2/graph_crawler/infrastructure/messaging/worker_api.py +0 -607
  764. graph_crawler-5.3.2/graph_crawler/infrastructure/persistence/__init__.py +0 -135
  765. graph_crawler-5.3.2/graph_crawler/infrastructure/persistence/auto_storage.py +0 -336
  766. graph_crawler-5.3.2/graph_crawler/infrastructure/persistence/base.py +0 -111
  767. graph_crawler-5.3.2/graph_crawler/infrastructure/persistence/eviction.py +0 -100
  768. graph_crawler-5.3.2/graph_crawler/infrastructure/persistence/graph_repository.py +0 -401
  769. graph_crawler-5.3.2/graph_crawler/infrastructure/persistence/json/__init__.py +0 -10
  770. graph_crawler-5.3.2/graph_crawler/infrastructure/persistence/json_storage.py +0 -375
  771. graph_crawler-5.3.2/graph_crawler/infrastructure/persistence/lmdb_eviction_storage.py +0 -401
  772. graph_crawler-5.3.2/graph_crawler/infrastructure/persistence/memory/__init__.py +0 -1
  773. graph_crawler-5.3.2/graph_crawler/infrastructure/persistence/memory_dedup_store.py +0 -90
  774. graph_crawler-5.3.2/graph_crawler/infrastructure/persistence/memory_frontier.py +0 -180
  775. graph_crawler-5.3.2/graph_crawler/infrastructure/persistence/memory_politeness_store.py +0 -88
  776. graph_crawler-5.3.2/graph_crawler/infrastructure/persistence/memory_storage.py +0 -166
  777. graph_crawler-5.3.2/graph_crawler/infrastructure/persistence/mongodb_storage.py +0 -383
  778. graph_crawler-5.3.2/graph_crawler/infrastructure/persistence/naming_strategy.py +0 -174
  779. graph_crawler-5.3.2/graph_crawler/infrastructure/persistence/postgresql_storage.py +0 -449
  780. graph_crawler-5.3.2/graph_crawler/infrastructure/persistence/protocols/__init__.py +0 -1
  781. graph_crawler-5.3.2/graph_crawler/infrastructure/persistence/redis_dedup_store.py +0 -119
  782. graph_crawler-5.3.2/graph_crawler/infrastructure/persistence/redis_politeness_store.py +0 -122
  783. graph_crawler-5.3.2/graph_crawler/infrastructure/persistence/repository.py +0 -130
  784. graph_crawler-5.3.2/graph_crawler/infrastructure/persistence/sqlite/__init__.py +0 -10
  785. graph_crawler-5.3.2/graph_crawler/infrastructure/persistence/sqlite_eviction_storage.py +0 -918
  786. graph_crawler-5.3.2/graph_crawler/infrastructure/persistence/sqlite_storage.py +0 -775
  787. graph_crawler-5.3.2/graph_crawler/infrastructure/persistence/unified/__init__.py +0 -47
  788. graph_crawler-5.3.2/graph_crawler/infrastructure/persistence/unified/file_job_storage.py +0 -245
  789. graph_crawler-5.3.2/graph_crawler/infrastructure/persistence/unified/file_queue_storage.py +0 -248
  790. graph_crawler-5.3.2/graph_crawler/infrastructure/persistence/unified/memory_job_storage.py +0 -94
  791. graph_crawler-5.3.2/graph_crawler/infrastructure/persistence/unified/memory_queue_storage.py +0 -117
  792. graph_crawler-5.3.2/graph_crawler/infrastructure/persistence/unified/postgresql_job_storage.py +0 -317
  793. graph_crawler-5.3.2/graph_crawler/infrastructure/persistence/unified/postgresql_queue_storage.py +0 -364
  794. graph_crawler-5.3.2/graph_crawler/infrastructure/persistence/unified/unified_storage.py +0 -244
  795. graph_crawler-5.3.2/graph_crawler/infrastructure/transport/__init__.py +0 -135
  796. graph_crawler-5.3.2/graph_crawler/infrastructure/transport/async_http/__init__.py +0 -38
  797. graph_crawler-5.3.2/graph_crawler/infrastructure/transport/async_http/config.py +0 -47
  798. graph_crawler-5.3.2/graph_crawler/infrastructure/transport/async_http/context.py +0 -55
  799. graph_crawler-5.3.2/graph_crawler/infrastructure/transport/async_http/driver.py +0 -724
  800. graph_crawler-5.3.2/graph_crawler/infrastructure/transport/async_http/driver_curl_cffi.py +0 -407
  801. graph_crawler-5.3.2/graph_crawler/infrastructure/transport/async_http/plugins/__init__.py +0 -48
  802. graph_crawler-5.3.2/graph_crawler/infrastructure/transport/async_http/plugins/autothrottle.py +0 -484
  803. graph_crawler-5.3.2/graph_crawler/infrastructure/transport/async_http/plugins/autothrottle_adaptive.py +0 -1435
  804. graph_crawler-5.3.2/graph_crawler/infrastructure/transport/async_http/plugins/headers.py +0 -69
  805. graph_crawler-5.3.2/graph_crawler/infrastructure/transport/async_http/plugins/http_cache.py +0 -321
  806. graph_crawler-5.3.2/graph_crawler/infrastructure/transport/async_http/plugins/rate_limiter.py +0 -96
  807. graph_crawler-5.3.2/graph_crawler/infrastructure/transport/async_http/plugins/retry.py +0 -316
  808. graph_crawler-5.3.2/graph_crawler/infrastructure/transport/async_http/stages.py +0 -33
  809. graph_crawler-5.3.2/graph_crawler/infrastructure/transport/base.py +0 -324
  810. graph_crawler-5.3.2/graph_crawler/infrastructure/transport/base_plugin.py +0 -151
  811. graph_crawler-5.3.2/graph_crawler/infrastructure/transport/compression/__init__.py +0 -23
  812. graph_crawler-5.3.2/graph_crawler/infrastructure/transport/compression/strategy.py +0 -219
  813. graph_crawler-5.3.2/graph_crawler/infrastructure/transport/connection_pool.py +0 -349
  814. graph_crawler-5.3.2/graph_crawler/infrastructure/transport/context.py +0 -114
  815. graph_crawler-5.3.2/graph_crawler/infrastructure/transport/core/__init__.py +0 -15
  816. graph_crawler-5.3.2/graph_crawler/infrastructure/transport/core/base_async.py +0 -378
  817. graph_crawler-5.3.2/graph_crawler/infrastructure/transport/core/body_decoder.py +0 -26
  818. graph_crawler-5.3.2/graph_crawler/infrastructure/transport/core/mixins.py +0 -258
  819. graph_crawler-5.3.2/graph_crawler/infrastructure/transport/core/redirect_utils.py +0 -168
  820. graph_crawler-5.3.2/graph_crawler/infrastructure/transport/escalation.py +0 -950
  821. graph_crawler-5.3.2/graph_crawler/infrastructure/transport/factory.py +0 -210
  822. graph_crawler-5.3.2/graph_crawler/infrastructure/transport/playwright/__init__.py +0 -19
  823. graph_crawler-5.3.2/graph_crawler/infrastructure/transport/playwright/adaptive_semaphore.py +0 -65
  824. graph_crawler-5.3.2/graph_crawler/infrastructure/transport/playwright/batch_scheduler.py +0 -764
  825. graph_crawler-5.3.2/graph_crawler/infrastructure/transport/playwright/browser_factory.py +0 -580
  826. graph_crawler-5.3.2/graph_crawler/infrastructure/transport/playwright/browser_profile.py +0 -718
  827. graph_crawler-5.3.2/graph_crawler/infrastructure/transport/playwright/config.py +0 -84
  828. graph_crawler-5.3.2/graph_crawler/infrastructure/transport/playwright/context.py +0 -46
  829. graph_crawler-5.3.2/graph_crawler/infrastructure/transport/playwright/driver.py +0 -80
  830. graph_crawler-5.3.2/graph_crawler/infrastructure/transport/playwright/engine.py +0 -480
  831. graph_crawler-5.3.2/graph_crawler/infrastructure/transport/playwright/fetch_metrics.py +0 -115
  832. graph_crawler-5.3.2/graph_crawler/infrastructure/transport/playwright/net/__init__.py +0 -41
  833. graph_crawler-5.3.2/graph_crawler/infrastructure/transport/playwright/net/geoip.py +0 -136
  834. graph_crawler-5.3.2/graph_crawler/infrastructure/transport/playwright/net/proxy_pool.py +0 -225
  835. graph_crawler-5.3.2/graph_crawler/infrastructure/transport/playwright/net/rate_limiter.py +0 -139
  836. graph_crawler-5.3.2/graph_crawler/infrastructure/transport/playwright/page_actions.py +0 -186
  837. graph_crawler-5.3.2/graph_crawler/infrastructure/transport/playwright/page_fetch.py +0 -968
  838. graph_crawler-5.3.2/graph_crawler/infrastructure/transport/playwright/plugins/__init__.py +0 -71
  839. graph_crawler-5.3.2/graph_crawler/infrastructure/transport/playwright/plugins/_network_record.py +0 -66
  840. graph_crawler-5.3.2/graph_crawler/infrastructure/transport/playwright/plugins/captcha_detector.py +0 -315
  841. graph_crawler-5.3.2/graph_crawler/infrastructure/transport/playwright/plugins/captcha_solver.py +0 -108
  842. graph_crawler-5.3.2/graph_crawler/infrastructure/transport/playwright/plugins/cookie_consent.py +0 -565
  843. graph_crawler-5.3.2/graph_crawler/infrastructure/transport/playwright/plugins/form_filler.py +0 -177
  844. graph_crawler-5.3.2/graph_crawler/infrastructure/transport/playwright/plugins/human_bezier.py +0 -297
  845. graph_crawler-5.3.2/graph_crawler/infrastructure/transport/playwright/plugins/network_log.py +0 -406
  846. graph_crawler-5.3.2/graph_crawler/infrastructure/transport/playwright/plugins/ram_adaptive.py +0 -208
  847. graph_crawler-5.3.2/graph_crawler/infrastructure/transport/playwright/plugins/screenshot.py +0 -169
  848. graph_crawler-5.3.2/graph_crawler/infrastructure/transport/playwright/plugins/user_profile.py +0 -556
  849. graph_crawler-5.3.2/graph_crawler/infrastructure/transport/playwright/pool_lifecycle.py +0 -658
  850. graph_crawler-5.3.2/graph_crawler/infrastructure/transport/playwright/pooled_driver.py +0 -704
  851. graph_crawler-5.3.2/graph_crawler/infrastructure/transport/playwright/stages.py +0 -35
  852. graph_crawler-5.3.2/graph_crawler/infrastructure/transport/playwright/stealth_hints.py +0 -153
  853. graph_crawler-5.3.2/graph_crawler/infrastructure/transport/plugin_manager.py +0 -316
  854. graph_crawler-5.3.2/graph_crawler/infrastructure/transport/protocols.py +0 -118
  855. graph_crawler-5.3.2/graph_crawler/infrastructure/transport/undetected/__init__.py +0 -8
  856. graph_crawler-5.3.2/graph_crawler/infrastructure/transport/undetected/async_driver.py +0 -465
  857. graph_crawler-5.3.2/graph_crawler/native/__init__.py +0 -199
  858. graph_crawler-5.3.2/graph_crawler/native/bloom_filter.pyx +0 -255
  859. graph_crawler-5.3.2/graph_crawler/native/html_parser.pyx +0 -262
  860. graph_crawler-5.3.2/graph_crawler/native/setup.py +0 -103
  861. graph_crawler-5.3.2/graph_crawler/native/url_utils.pyx +0 -209
  862. graph_crawler-5.3.2/graph_crawler/observability/__init__.py +0 -62
  863. graph_crawler-5.3.2/graph_crawler/observability/decorators/__init__.py +0 -11
  864. graph_crawler-5.3.2/graph_crawler/observability/decorators/cache.py +0 -126
  865. graph_crawler-5.3.2/graph_crawler/observability/decorators/log.py +0 -56
  866. graph_crawler-5.3.2/graph_crawler/observability/decorators/retry.py +0 -121
  867. graph_crawler-5.3.2/graph_crawler/observability/decorators/timing.py +0 -43
  868. graph_crawler-5.3.2/graph_crawler/observability/error_tracing.py +0 -361
  869. graph_crawler-5.3.2/graph_crawler/observability/extensions/__init__.py +0 -18
  870. graph_crawler-5.3.2/graph_crawler/observability/extensions/memory_guard.py +0 -237
  871. graph_crawler-5.3.2/graph_crawler/observability/extensions/state_manager.py +0 -319
  872. graph_crawler-5.3.2/graph_crawler/observability/listeners/__init__.py +0 -33
  873. graph_crawler-5.3.2/graph_crawler/observability/listeners/base.py +0 -82
  874. graph_crawler-5.3.2/graph_crawler/observability/listeners/base_metrics_listener.py +0 -18
  875. graph_crawler-5.3.2/graph_crawler/observability/listeners/crawl_listener.py +0 -28
  876. graph_crawler-5.3.2/graph_crawler/observability/listeners/dlq_listener.py +0 -215
  877. graph_crawler-5.3.2/graph_crawler/observability/listeners/error_listener.py +0 -18
  878. graph_crawler-5.3.2/graph_crawler/observability/listeners/logging_listener.py +0 -88
  879. graph_crawler-5.3.2/graph_crawler/observability/listeners/metrics_listener.py +0 -109
  880. graph_crawler-5.3.2/graph_crawler/observability/listeners/node_listener.py +0 -33
  881. graph_crawler-5.3.2/graph_crawler/observability/listeners/plugin_listener.py +0 -28
  882. graph_crawler-5.3.2/graph_crawler/observability/listeners/storage_listener.py +0 -21
  883. graph_crawler-5.3.2/graph_crawler/observability/listeners/url_listener.py +0 -29
  884. graph_crawler-5.3.2/graph_crawler/observability/metrics/__init__.py +0 -23
  885. graph_crawler-5.3.2/graph_crawler/observability/metrics/memory_profiler.py +0 -508
  886. graph_crawler-5.3.2/graph_crawler/observability/metrics/metrics_collector.py +0 -408
  887. graph_crawler-5.3.2/graph_crawler/observability/metrics/prometheus_metrics.py +0 -293
  888. graph_crawler-5.3.2/graph_crawler/observability/metrics_core.py +0 -389
  889. graph_crawler-5.3.2/graph_crawler/observability/structured_logging.py +0 -216
  890. graph_crawler-5.3.2/graph_crawler/observability/tracing.py +0 -291
  891. graph_crawler-5.3.2/graph_crawler/optimizations/__init__.py +0 -89
  892. graph_crawler-5.3.2/graph_crawler/optimizations/generators.py +0 -477
  893. graph_crawler-5.3.2/graph_crawler/optimizations/memory_slots.py +0 -641
  894. graph_crawler-5.3.2/graph_crawler/optimizations/simhash_numba.py +0 -284
  895. graph_crawler-5.3.2/graph_crawler/shared/__init__.py +0 -25
  896. graph_crawler-5.3.2/graph_crawler/shared/constants.py +0 -938
  897. graph_crawler-5.3.2/graph_crawler/shared/dto/__init__.py +0 -38
  898. graph_crawler-5.3.2/graph_crawler/shared/dto/edge_dto.py +0 -52
  899. graph_crawler-5.3.2/graph_crawler/shared/dto/graph_dto.py +0 -97
  900. graph_crawler-5.3.2/graph_crawler/shared/dto/node_dto.py +0 -193
  901. graph_crawler-5.3.2/graph_crawler/shared/error_handling/__init__.py +0 -15
  902. graph_crawler-5.3.2/graph_crawler/shared/error_handling/error_handler.py +0 -333
  903. graph_crawler-5.3.2/graph_crawler/shared/exceptions.py +0 -394
  904. graph_crawler-5.3.2/graph_crawler/shared/platform/__init__.py +0 -125
  905. graph_crawler-5.3.2/graph_crawler/shared/platform/adaptive_resolver.py +0 -414
  906. graph_crawler-5.3.2/graph_crawler/shared/platform/config.py +0 -635
  907. graph_crawler-5.3.2/graph_crawler/shared/platform/detector.py +0 -334
  908. graph_crawler-5.3.2/graph_crawler/shared/platform/diagnostics.py +0 -660
  909. graph_crawler-5.3.2/graph_crawler/shared/platform/metrics.py +0 -299
  910. graph_crawler-5.3.2/graph_crawler/shared/security/__init__.py +0 -22
  911. graph_crawler-5.3.2/graph_crawler/shared/security/url_sanitizer.py +0 -100
  912. graph_crawler-5.3.2/graph_crawler/shared/security/url_validator.py +0 -299
  913. graph_crawler-5.3.2/graph_crawler/shared/utils/__init__.py +0 -212
  914. graph_crawler-5.3.2/graph_crawler/shared/utils/async_compat.py +0 -140
  915. graph_crawler-5.3.2/graph_crawler/shared/utils/bloom_filter.py +0 -373
  916. graph_crawler-5.3.2/graph_crawler/shared/utils/captcha/__init__.py +0 -36
  917. graph_crawler-5.3.2/graph_crawler/shared/utils/captcha/base.py +0 -92
  918. graph_crawler-5.3.2/graph_crawler/shared/utils/captcha/manager.py +0 -474
  919. graph_crawler-5.3.2/graph_crawler/shared/utils/celery_config.py +0 -332
  920. graph_crawler-5.3.2/graph_crawler/shared/utils/celery_helpers.py +0 -153
  921. graph_crawler-5.3.2/graph_crawler/shared/utils/cgroup_limits.py +0 -227
  922. graph_crawler-5.3.2/graph_crawler/shared/utils/content_decoder.py +0 -150
  923. graph_crawler-5.3.2/graph_crawler/shared/utils/distributed_rate_limiter.py +0 -265
  924. graph_crawler-5.3.2/graph_crawler/shared/utils/distributed_rate_limiter_backends.py +0 -284
  925. graph_crawler-5.3.2/graph_crawler/shared/utils/dns_cache.py +0 -370
  926. graph_crawler-5.3.2/graph_crawler/shared/utils/enterprise_ua_generator.py +0 -294
  927. graph_crawler-5.3.2/graph_crawler/shared/utils/event_publisher_mixin.py +0 -187
  928. graph_crawler-5.3.2/graph_crawler/shared/utils/fast_json.py +0 -240
  929. graph_crawler-5.3.2/graph_crawler/shared/utils/fingerprint.py +0 -36
  930. graph_crawler-5.3.2/graph_crawler/shared/utils/fingerprint_data.py +0 -99
  931. graph_crawler-5.3.2/graph_crawler/shared/utils/fingerprint_generators.py +0 -128
  932. graph_crawler-5.3.2/graph_crawler/shared/utils/fingerprint_profile.py +0 -121
  933. graph_crawler-5.3.2/graph_crawler/shared/utils/fingerprint_stealth.py +0 -105
  934. graph_crawler-5.3.2/graph_crawler/shared/utils/html_utils.py +0 -118
  935. graph_crawler-5.3.2/graph_crawler/shared/utils/id_generator.py +0 -195
  936. graph_crawler-5.3.2/graph_crawler/shared/utils/memory_optimizer.py +0 -536
  937. graph_crawler-5.3.2/graph_crawler/shared/utils/rate_limiter.py +0 -185
  938. graph_crawler-5.3.2/graph_crawler/shared/utils/regex_validator.py +0 -966
  939. graph_crawler-5.3.2/graph_crawler/shared/utils/shadow_dom.py +0 -36
  940. graph_crawler-5.3.2/graph_crawler/shared/utils/text_utils.py +0 -387
  941. graph_crawler-5.3.2/graph_crawler/shared/utils/url_patterns.py +0 -135
  942. graph_crawler-5.3.2/graph_crawler/shared/utils/url_utils.py +0 -595
  943. graph_crawler-5.3.2/graph_crawler/shared/utils/user_agent_rotator.py +0 -333
  944. graph_crawler-5.3.2/graph_crawler/shared/utils/validation_helpers.py +0 -225
  945. graph_crawler-5.3.2/graph_crawler/shared/utils/visualization.py +0 -134
  946. graph_crawler-5.3.2/graph_crawler/shared/utils/visualization_core.py +0 -566
  947. graph_crawler-5.3.2/graph_crawler/tools/__init__.py +0 -1
  948. graph_crawler-5.3.2/graph_crawler/tools/db_cleanup.py +0 -263
  949. graph_crawler-5.3.2/graph_crawler.egg-info/PKG-INFO +0 -531
  950. graph_crawler-5.3.2/graph_crawler.egg-info/SOURCES.txt +0 -479
  951. graph_crawler-5.3.2/pyproject.toml +0 -301
  952. graph_crawler-5.3.2/setup.cfg +0 -4
  953. {graph_crawler-5.3.2 → graph_crawler-5.3.4}/graph_crawler/py.typed +0 -0
  954. {graph_crawler-5.3.2 → graph_crawler-5.3.4}/graph_crawler.egg-info/dependency_links.txt +0 -0
  955. {graph_crawler-5.3.2 → graph_crawler-5.3.4}/graph_crawler.egg-info/entry_points.txt +0 -0
  956. {graph_crawler-5.3.2 → graph_crawler-5.3.4}/graph_crawler.egg-info/requires.txt +0 -0
  957. {graph_crawler-5.3.2 → graph_crawler-5.3.4}/graph_crawler.egg-info/top_level.txt +0 -0
@@ -0,0 +1,429 @@
1
+ # Changelog
2
+
3
+ ## 5.3.4 — 2026-10
4
+
5
+ ### Fixed
6
+
7
+ - **The per-node enrichment limit measures active work, not the HTML-pool queue.** `NodeScanner` wraps
8
+ `enrich_node` in `enrich_budget(seconds)` (`graph_crawler.domain.entities.node`): while a call waits for a thread
9
+ of the HTML executor in `run_in_html_pool` (parse, `_update_from_context`, hashes), the deadline is suspended and
10
+ resumed with the same remainder the moment the work starts. With 5.3.3 the hook and the hashes moved into the
11
+ shared pool, so under load a node's wall-clock depended on how many neighbours stood in front of it: a burst of
12
+ large pages produced a cascade of `Per-node timeout … marking as ERROR` for pages whose own processing took a
13
+ fraction of the limit (and every stage re-queued behind the others). A page whose **own** processing exceeds
14
+ `node_enrich_timeout` still times out and still returns its discovered links. The crawl-level timeout remains the
15
+ upper bound for a node that waits in the queue.
16
+ - **`IsolatedExecutor.run` admits at most `max_workers` tasks at a time** (`threading.BoundedSemaphore`): the task
17
+ `timeout` now measures execution in the child process, not the wait behind other tasks. Previously a burst of
18
+ submissions could expire the timeout of a queued task, which killed the whole pool and failed every task in flight.
19
+
20
+ - **Control commands are no longer dropped silently.** `GraphSpider.process_control_messages` executes only
21
+ `SPIDER_COMMANDS` (`STOP`, `PAUSE`, `RESUME`, `REPRIORITIZE`, `FORCE_VISIT`); any other `CrawlCommand` logs
22
+ `WARNING Unsupported control command '<value>' from <sender> is ignored (supported: ...)` once per command type
23
+ per crawl (repeats at `DEBUG`) and the crawl goes on. `REPRIORITIZE` without `url`/`priority` and `FORCE_VISIT`
24
+ without `url` log a `WARNING` with the received `data` instead of doing nothing.
25
+
26
+ ### Added
27
+
28
+ - `EnrichBudget` (`pause()` / `resume()`) and `enrich_budget()` in `graph_crawler.domain.entities.node`.
29
+ - `SPIDER_COMMANDS` (`graph_crawler.domain.interfaces`): the commands `GraphSpider` executes.
30
+
31
+ ### Deprecated
32
+
33
+ - `CrawlCommand.SKIP_URL`, `CHANGE_STRATEGY`, `SET_DEPTH_LIMIT`, `REQUEST_STATE`, `UPDATE_GOAL` were never executed
34
+ by the spider. They will be removed from the enum in 5.4.0.
35
+
36
+ ## 5.3.3 — 2026-10
37
+
38
+ ### Added
39
+
40
+ - **`IsolatedExecutor` / `IsolatedTaskError`** (`from graph_crawler import IsolatedExecutor`). Runs CPU-bound functions
41
+ in a `spawn` process pool: a native crash (SIGSEGV in libxml2/lxml, trafilatura, any C extension) or a hang of a
42
+ worker becomes `IsolatedTaskError(reason="crashed" | "timeout" | "unavailable")` in the caller, the pool restarts
43
+ and the crawl goes on. Tasks that shared the broken pool are retried once; a hung worker is killed after
44
+ `timeout` (default `DEFAULT_ISOLATED_TASK_TIMEOUT` = 30 s). Ordinary exceptions of the function propagate as is.
45
+ - **`CrawlerConfig.node_enrich_timeout`** and `crawl(..., node_enrich_timeout=...)` / `async_crawl(...)` /
46
+ `GraphCrawlerClient.crawl(...)`: per-node enrichment limit (HTML parse, plugins, subclass hook, hashes).
47
+ `None` keeps `DEFAULT_NODE_ENRICH_TIMEOUT` (45 s, `shared.constants`). `NodeScanner(driver, enrich_timeout=...)`.
48
+ - `run_in_html_pool(fn, *args)` (`graph_crawler.domain.entities.node`): runs `fn` in the HTML executor under its
49
+ semaphore. `Node.pop_discovered_links()` returns links extracted on `ON_HTML_PARSED` of an interrupted
50
+ `enrich_node`.
51
+ - `URLRuleMatcher.rule_matches(rule, url)`.
52
+
53
+ ### Changed
54
+
55
+ - **The `Node._update_from_context` hook and `get_content_hash`/`get_simhash` run in the HTML executor** under the
56
+ same semaphore as HTML parsing (they used the default `asyncio.to_thread` pool, `min(32, cpu+4)` threads, outside
57
+ the CPU budget). Concurrency of heavy subclass code is now bounded by `GRAPH_CRAWLER_HTML_PARSER_WORKERS`
58
+ (default — the cgroup CPU quota); `=1` serialises it completely. Code that is not thread-safe must use its own
59
+ lock or `GRAPH_CRAWLER_HTML_PARSER_WORKERS=1`; native code that can crash — `IsolatedExecutor`.
60
+ - **One URL rule — one decision.** `CrawlScheduler`, `LinkProcessor` and `RuleBasedScheduler` share
61
+ `URLRuleMatcher`: first match in list order, `SmartURLRule` is matched against its `scope` (the scheduler used to
62
+ run `re.search` over the full URL, so `SmartURLRule(r"/help", scope=PATH, should_scan=False)` excluded
63
+ `https://helpware.com/`). `GraphSpider` no longer copies `url_rules` with `should_scan=False` into `PathFilter`
64
+ (it applied them to the path, ignoring order and scope); `excluded_paths` / `included_paths` are unchanged.
65
+ - A URL rule whose `priority` is outside `[MIN_URL_PRIORITY, MAX_URL_PRIORITY]` (`[-100, 100]`) gets a WARNING when
66
+ the scheduler is created: `priority` is a queue position and is clamped; rule precedence is list order.
67
+ - `IDriver.fetch(url, *, referer, extra_headers, cookies)` is the contract of every driver: `BaseDriver`,
68
+ `EscalatingDriver` (caller cookies/headers merged with the host session — the session wins on a cookie name
69
+ clash, the session `User-Agent` is applied on top for HTTP/TLS tiers), `PooledPlaywrightDriver` (`extra_headers`),
70
+ `IAsyncDriver`, `IBrowserDriver`. `BaseDriver.fetch_many` passes per-URL `extra_headers_list` / `cookies_list` to
71
+ `fetch` (they were dropped).
72
+
73
+ ### Fixed
74
+
75
+ - **Per-node timeout no longer drops discovered links.** `scan_node` / `scan_batch` return the links extracted on
76
+ `ON_HTML_PARSED` when enrichment exceeds the limit; the node is still `ERROR` / `FAILED`. Large listing pages, the
77
+ first to hit the limit, keep their edges.
78
+
79
+ ## 5.3.2 — 2026-06
80
+
81
+ ### Added
82
+
83
+ - **Fetch provenance on the node.** `Node.channel`, `bot_block_status`, `served_by_driver`, `served_by_engine`,
84
+ `escalations` and `fetch_info` read `metadata["fetch"]`; `Node.ok` (scanned, 2xx/3xx, not blocked, no error) and
85
+ `Node.is_blocked` separate useful pages from block and error pages.
86
+ - **Plugin routing.** `BaseNodePlugin.domains` (domain and subdomains) and `url_pattern` (regex), on the class or via
87
+ `config={"domains": [...], "url_pattern": ...}`, plus an overridable `applies_to(url)`. An invalid `url_pattern`
88
+ raises `ConfigurationError` on `register()`. Several instances of one plugin class with different routes run
89
+ side by side (they used to replace each other).
90
+ - **Typed plugin output.** `NodePluginContext.set_node_field(name, value)` writes a field declared by a `Node`
91
+ subclass, validated against its annotation (`"100"` → `int`); base fields are read-only. Fields are rolled back
92
+ together with `metadata`/`user_data` when the plugin fails.
93
+ - **Empty extraction warning.** `BaseNodePlugin.expects_nonempty` + `extraction_key`: a WARNING when the plugin left
94
+ `user_data[extraction_key]` empty.
95
+ - **`Graph.search(..., user_data_keys=("jobs",))`** searches the listed `user_data` keys as well.
96
+ - **`Node.public_user_data`** and `RESERVED_USER_DATA_KEYS` (`_link_anchors`, `_custom_fields`, `_node_class`).
97
+
98
+ ### Changed
99
+
100
+ - A response with status 400 or higher gets `metadata["error"] = "HTTP <code>"` and is logged as a WARNING
101
+ (`HTTP 404 for <url> — page not scanned`).
102
+ - A bare 403/401/405 without vendor markers is still classified as `none`; the decision is now logged at INFO.
103
+ - Quieter logs: import writes nothing at INFO, platform detection runs once, the start of a crawl is one line,
104
+ and each page is one INFO line with `[channel=…]`, `[block=…]`, `[error=…]`.
105
+ - The temporary `_link_anchors` map is removed from the node once its edges are created (the anchor text stays in
106
+ `edge.metadata["anchor_text"]`). The default JSON export writes `public_user_data`.
107
+ - A third-party plugin that overwrites a reserved `user_data` key gets a WARNING.
108
+
109
+ ### Fixed
110
+
111
+ - `load_graph()` without `node_class=` restores a custom `Node` subclass when its module is already imported (the
112
+ class name is stored with the node; nothing is imported from the file). `Graph.copy()`, `union`, `intersection`,
113
+ `difference` and nodes created in a loaded graph keep the node class.
114
+ - `metadata` written by a plugin on `ON_NODE_CREATED` or `ON_AFTER_SCAN` is no longer lost.
115
+ - **Placeholder lists are detected as a JavaScript shell.** A 2xx body with five or more `placeholder` /
116
+ `skeleton` / `shimmer` elements makes `needs_browser` true, so `escalating` goes straight to the browser tier.
117
+ With `driver="http"` the node gets `metadata["js_shell_suspected"]` and a WARNING (once per host) suggests
118
+ `driver="escalating"` or `"playwright"`.
119
+ - **No duplicate edges.** A link repeated on a page (menu + footer + body) created a new `Edge` each time
120
+ (17.5 % of edges on uk.wikipedia); `LinkProcessor` now skips existing `(source, target)` pairs. `Graph.has_edge`
121
+ also sees the backend edge index.
122
+ - **`h1` children are no longer joined with spaces** (`Портал : Поточні події` → `Портал:Поточні події`).
123
+ - **Default ports are normalized** (`http://x:80`, `https://x:443`, empty port).
124
+ - `Graph.normalize_url()` is public; `LinkProcessor` checks the scheduler with the canonical form as well.
125
+ - **`NetworkLogPlugin` waits for network quiet** before publishing the log (`settle_ms`=2000, `quiet_ms`=300;
126
+ `settle_ms=0` restores the old behaviour) — late XHR (search/listing after hydration) was lost.
127
+ - `create_trailing_slash_rule` keeps the root path; an empty path is `/` for PATH-scope rules.
128
+
129
+ ## 5.3.1 — 2026-06
130
+
131
+ ### Added
132
+
133
+ - **Hydration state globals snapshot.** The Playwright driver serialises `window.__NAME__` objects (`__NUXT__`,
134
+ `__APOLLO_STATE__`, `__INITIAL_STATE__`, `__PINIA__`, …) with `JSON.stringify` after the page has run and embeds
135
+ them into the HTML snapshot as `<script type="application/json" data-agc-state="__NAME__">`. Nuxt 2 ships its
136
+ state as an IIFE (`window.__NUXT__=(function(a,b){return {…}}(…))`) which is JavaScript, not JSON, and was
137
+ invisible to any static state parser. Globals that already exist as a JSON `<script id="__NAME__">`
138
+ (`__NEXT_DATA__`) are not duplicated; `PageFetcher.state_globals_max_chars` (5 MB) caps the snapshot.
139
+ `inject_state_globals(html, states)` is exported for tests and other drivers.
140
+
141
+ ## 5.3.0 — 2026-06
142
+
143
+ ### Added
144
+
145
+ - **Page actions as public API.** `driver_config={"actions": [PageAction(...) | dict, ...]}` for the Playwright driver:
146
+ `click` / `fill` / `select` / `press` / `wait_for(response=…|selector=…)` / `scroll`, target by `selector`, `text`,
147
+ `placeholder` or `label` (`nth` among visible matches). Actions are validated when the driver is created and run
148
+ after content is ready and before the HTML snapshot and `CONTENT_READY` hooks — the network log is published after
149
+ the actions. Results land in `node.metadata["actions_log"]`, `["requests_after_actions"]` and `["actions_error"]`
150
+ (the first failing action stops the chain with a reason). `from graph_crawler import PageAction`.
151
+ - `engine.page_error_types()` — page error classes of all installed browser SDKs.
152
+ - `PageAction(type="back")`; action errors name the element that intercepts pointer events.
153
+
154
+ ### Fixed
155
+
156
+ - Binary request bodies (gzip beacons) no longer raise `UnicodeDecodeError` inside Playwright event listeners
157
+ (`NetworkLogPlugin` and the action recorder read `post_data_buffer` with `errors="replace"`); the error used to break
158
+ the next Playwright call with `TypeError: function takes exactly 5 arguments`.
159
+
160
+ ### Fixed
161
+
162
+ - `graph.get_node_by_url(seed)` finds the node after a redirect in the graph returned by `async_crawl`: `add_node`
163
+ restores the alias from `metadata["was_redirected_from"]`.
164
+
165
+ ## 5.2.2 — 2026-06
166
+
167
+ ### Fixed (test infrastructure)
168
+
169
+ - **The library no longer configures logging.** `GraphCrawlerClient.__init__` called `logging.basicConfig(INFO)`
170
+ when its logger had no handlers, so every crawl printed to stderr and reconfigured the application's root
171
+ logger. Removed; `graph_crawler` gets a `NullHandler`.
172
+ - **Noise demoted:** `HTML executor shutdown` and `lmdb not installed … Falling back to SQLiteEvictionStorage` are
173
+ DEBUG; `channel='chrome' not installed, falling back to bundled Chromium` is a WARNING once per process.
174
+ - **One version source.** `graph_crawler.__version__` (and the default User-Agent) come from the installed
175
+ package metadata (`pyproject.toml`); `__version__.py` no longer hard-codes a number that drifted (5.1.0 vs 5.2.0).
176
+ - **Test suite collects without optional extras.** Tests that need `psutil`, `rapidfuzz`, `stop-words`,
177
+ `html2md-clean` or `playwright` are skipped via `importorskip` instead of failing collection under `-x`.
178
+ `test_div_inline_fix.py` / `test_phase1_fixes.py` tested `html2md_clean` itself (no `graph_crawler` code) and were
179
+ removed from the core suite.
180
+ - GitLab CI (`.gitlab-ci.yml`): offline suite with `[dev]` and a minimal job without extras.
181
+
182
+ ## 5.2.1 — 2026-06
183
+
184
+ ### Fixed (freelance cases)
185
+
186
+ - **Captured XHR/fetch traffic could not be replayed outside the browser.** `NetworkLogPlugin` recorded the
187
+ URL and method of a request but not its body, so every POST/GraphQL endpoint (robota.ua lists vacancies via
188
+ `POST dracula.robota.ua/?q=getPublishedVacanciesList`) was unusable: a GET of the same URL returns 400.
189
+ Records now carry `post_data` and (on `response`) `request_headers`.
190
+ - **GraphQL responses overwrote each other.** `body_ref` was `sha1(url|status|content-type)` — all operations
191
+ POSTed to one `/graphql` URL shared a key and only the last body survived. The key now includes method and
192
+ request body.
193
+ - **JSON family by default.** The capture allow-list matched exact MIME types only; `application/graphql-
194
+ response+json`, `problem+json`, `vnd.api+json`, `text/json` were dropped. Without an explicit
195
+ `capture_content_types` every `*/json` and `*+json` type is captured (RFC 6839). Default `max_body_kb` 64 → 256
196
+ (listing APIs routinely exceed 64 KB).
197
+ - **Shadow DOM was invisible.** `page.content()` serializes only light DOM: content of open shadow roots (web
198
+ components, embedded price widgets) never reached the node. When a page has open shadow roots, the browser
199
+ driver serializes it with `Element.getHTML({shadowRoots})` and expands the declarative shadow roots into their
200
+ hosts (`shared/utils/shadow_dom.expose_shadow_roots`) — Lexbor, like the HTML spec, does not descend into
201
+ `<template>` content, so a plain declarative-shadow-DOM serialization would still hide it from selectors and link
202
+ extraction. Pages without shadow roots are untouched.
203
+ - `tests/unit/domain/entities/test_graph_new_features.py` still expected the `DeprecationWarning` that
204
+ `export_nodes()` stopped emitting in 4aab7525; it now asserts the opposite.
205
+
206
+ ### Fixed (real-site tests)
207
+
208
+ - **Ctrl+C during `crawl()` hung until the crawl-level timeout** (28 s with `timeout=25`; forever without
209
+ one). `asyncio.wait_for` in Python 3.11 swallows the outer cancellation when the awaited coroutine finishes
210
+ at the same moment, so some workers survived `KeyboardInterrupt` and kept crawling. `NodeScanner` and the
211
+ escalation tier budget now use `asyncio.timeout()`; `CrawlCoordinator` cancels its workers on
212
+ `CancelledError`. Ctrl+C now returns in ~0.3 s.
213
+ - **`same_domain=False` was ignored** — without `allowed_domains` the `DomainFilter` default
214
+ (`domain+subdomains`) still applied and external links never entered the graph. Now maps to `allowed_domains=["*"]`.
215
+ - **`graph.metadata["stop_reason"]` was `None` after `timeout=` / `max_pages`** — only stop conditions were
216
+ recorded. Now `"timeout"`, `"max_pages"` or `"limit"`.
217
+ - **Network errors were invisible on the node**: a DNS/connection failure left `response_status=None`,
218
+ `scanned=True` and no message; `get_failed_nodes()` returned `[]`. The error text is now in
219
+ `node.metadata["error"]`, the HTTP status (if any) is kept, and `get_failed_nodes()` with default
220
+ arguments includes network-error nodes.
221
+ - **`storage="json", storage_config={"path": "site.json"}` was silently ignored** (file written to
222
+ `crawler_data/json/graph.json`). `path` is now honoured, like for sqlite (`JSONStorage(file_name=)`).
223
+ - `Graph.export_nodes()` / `Graph.export_edges()` are no longer deprecated: they are the public one-liners the
224
+ README shows and now delegate to `GraphExportUseCase` silently (no `DeprecationWarning`).
225
+ - `tests/manual/real_sites/run_all.py -j N` runs scenarios in parallel; `tests/manual/real_sites/test_user_cases.py`
226
+ — 23 pytest user scenarios on Wikipedia / robota.ua / GitHub / example.com, each hard-capped at 40 s.
227
+
228
+ ### Changed
229
+
230
+ - **Engine contract verified end-to-end**. `tests/transport/
231
+ test_engine_contract.py` drives the real `PlaywrightDriver.fetch()` through three engines registered via the
232
+ public `register_engine()` on a recording fake SDK: the call sequence is byte-for-byte identical across
233
+ engines, stealth is injected iff `provides_stealth is False`, and `executable_path`/`ignore_default_args`/
234
+ launch args come only from the engine. No runtime code changed.
235
+ - **`LexborDocument.clean_text()` no longer re-parses the page**. To strip `script/style/noscript/svg/head` without mutating the shared tree it
236
+ serialised the document and built a second `LexborHTMLParser` — i.e. every page with the default
237
+ `TextExtractorPlugin` was parsed twice (`count_parses.py`: 2.0 → **1.0** per page; with `MarkdownPlugin`
238
+ 1 parse + 1 clone). It now uses `tree.clone()`.
239
+ - **One `ContentDecoder` for every HTTP tier**. `AsyncDriver` (aiohttp) and `AsyncCurlCffiDriver` (curl_cffi) no longer rely on the client's own
240
+ `response.text`/`.text()`: they read the raw body and decode it through `ContentDecoder`
241
+ (`Content-Type` charset → `<meta charset>` → BOM → chardet → strict utf-8). Pages whose charset is only
242
+ declared in `<meta>` (e.g. windows-1251 without a header) were previously decoded as utf-8 by aiohttp,
243
+ failed, and silently became `html=None` with a "successful" 200. An undecodable body is now reported as
244
+ `FetchResponse.error` (`"ContentDecoder: cannot decode body …"`) with the status code preserved;
245
+ `ConnectionPoolManager.fetch_text()` goes through the same decoder. `FetchResponse.html` is a strict
246
+ `str` field — passing `bytes` raises `ValidationError` instead of being coerced. Browser tiers
247
+ (Playwright `page.content()`, nodriver `tab.get_content()`) already return `str`. Contract test:
248
+ `tests/transport/test_html_is_str_contract.py` (driver matrix returns `str`; cp1251 via meta/header;
249
+ binary → error).
250
+ - **Lazy public facade**. `graph_crawler/__init__.py` now
251
+ eagerly imports only `crawl`, `async_crawl`, `Graph`, `Node`, `save_graph`, `load_graph`,
252
+ `BaseStopCondition`; every other name in `__all__` (drivers, storages, exceptions, settings, views,
253
+ celery tasks, …) resolves on first access via module `__getattr__` and is cached. `aiohttp` is no longer
254
+ loaded by `import graph_crawler`. `bootstrap()` no longer calls `collect_system_metrics()`
255
+ (`psutil.cpu_percent(interval=0.1)` blocked import for 100 ms for a DEBUG line). Import time here:
256
+ 470 ms → 228 ms. Optional names (`PlaywrightDriver`, `celery`, `EasyDistributedCrawler`, …) still return
257
+ `None` without their extra.
258
+ - **Escalation re-probe replays the solving tier's User-Agent**.
259
+ Playwright and nodriver now export `navigator.userAgent` as `extras["user_agent"]`;
260
+ `SessionState.absorb` records it (pinned once the session is solved, like `impersonate`/`proxy`) and
261
+ `EscalatingDriver._fetch_tier` sends it as `extra_headers={"User-Agent": …}` to HTTP/TLS tiers together
262
+ with the stored cookies. `cf_clearance` is bound to UA+IP+JA4, so a re-probe on Tier 1 with aiohttp's
263
+ default UA was rejected and the host never descended from the browser tier.
264
+
265
+ ### Removed
266
+
267
+ - **`NodePluginContext.parser`**. Node plugins now read the
268
+ single Lexbor tree through the `HTMLDocument`/`HTMLNode` protocols: `LinkExtractorPlugin`
269
+ (`doc.css("a[href]")`, `doc.base_href()`), `MetadataExtractorPlugin`, `TextExtractorPlugin`
270
+ (`doc.clean_text()`, new in the protocol), `StructuredDataPlugin` (OG/Twitter/Microdata/RDFa parsers take
271
+ an `HTMLDocument`; `StructuredDataExtractor.extract(html=, doc=)`), `Email`/`PhoneExtractorPlugin`.
272
+ Migration: `context.parser.find_all(sel)` → `context.html_tree.css(sel)`, `.find()` → `.css_first()`,
273
+ `el.get_attribute()` → `el.attr()`. Fixed along the way in `LexborNode`: `attr()` returns `""` (not
274
+ `None`) for valueless boolean attributes such as `itemscope`, so nested Microdata/RDFa items are now
275
+ detected; `css()`/`css_first()` return descendants only (selectolax included the node itself, which made
276
+ Microdata recurse to `max_nesting_depth`).
277
+ - **`PooledPlaywrightDriver` legacy batch path**: `batch_legacy.py`
278
+ (`LegacyBatch._fetch_batch_legacy`, `_fetch_chain`) is gone. `persistent_browser=False` keeps its
279
+ "launch/stop per batch" semantics through the pool path: after a batch, once no fetch is in flight, the
280
+ pool and the engine session are closed (`_close_pool()` + `_stop_persistent_session()`, shared with
281
+ `close()`). Dead `self.playwright`/`self.browsers` cleanup removed from `close()`.
282
+ - **Escalation.** `classify_block()` rewritten to the
283
+ 6.0 decision table: challenge/captcha vendor headers first, then unambiguous body captcha/challenge
284
+ markers (ahead of vendor hard-block headers), then short/blocking-page widgets, status-based verdicts
285
+ and empty-2xx. A bare `401/403/405` with no vendor markers is no longer a block. On the classifier corpus
286
+ it goes 25/37 → **37/37**.
287
+
288
+ - `needs_browser` heuristic (SPA shell: little visible text + SPA root / `<noscript>` JS hint / no
289
+ `<a href>`) is now the default `EscalationPolicy.needs_browser`; on a clean HTTP/TLS response it jumps
290
+ straight to the first browser tier (`escalation_reason="needs_browser"`).
291
+ - Per-tier `TierTimeouts` + `escalation_deadline_s` (60s) budget: a tier is skipped (last response
292
+ returned, browser never started) when the remaining budget is below its `min_budget`; each tier fetch
293
+ is wrapped in `asyncio.wait_for`. New `PER_NODE_FETCH_TIMEOUT` constant with a validator warning.
294
+ - Cross-tier session: `SessionState` / `HostSessionStore` carry solved cookies (`cf_clearance`, `__cf_bm`,
295
+ `datadome`, …) forward and back down to cheaper tiers on re-probe; `impersonate`/`proxy` are pinned once
296
+ a session is solved. curl_cffi pins the impersonate fingerprint; Playwright/nodriver export context
297
+ cookies via `extras["cookies"]`.
298
+ - `extras` contract: every driver stamps `channel`/`driver`/`engine` (via `BaseDriver`/`BaseAsyncDriver`
299
+ `_stamp_extras` + `_finalize_response`) even outside escalation.
300
+ - New Prometheus metrics `crawl_fetch_duration_seconds{channel,engine}`, `crawl_escalations_total`,
301
+ `crawl_escalation_deadline_hits_total`.
302
+
303
+ - **HTML parsing: Lexbor (selectolax) is the only core parser**.
304
+ `beautifulsoup4`, `lxml`, `lxml_html_clean` removed from `[project].dependencies`;
305
+ `BeautifulSoupAdapter`, `LxmlAdapter`, `ScrapyAdapter` deleted. New `HTMLDocument` / `HTMLNode`
306
+ protocols in `domain/value_objects/html_document.py`, implemented by `LexborDocument` in
307
+ `infrastructure/adapters/selectolax_adapter.py`. `<template>` is renamed to `gc-template` before
308
+ parsing so Vue/React SSR links inside templates are not lost. `IParser.parse()` returns `HTMLDocument`;
309
+ `NodePluginContext.html_tree` is now a `LexborDocument`. `get_parser()` accepts `auto|selectolax|lexbor`.
310
+ - `HTMLUtils.extract_links/extract_text/extract_metadata` accept an `HTMLDocument` (string input still
311
+ works but is deprecated).
312
+ - `SitemapParser.parse_large_sitemap_streaming()` uses stdlib `iterparse` by default; lxml is an
313
+ optional fast-path via the new extra `sitemap-fast`.
314
+
315
+ - **`html2md-clean` moved to the optional extra `markdown`** (`pip install "graph-crawler[markdown]"`);
316
+ `MarkdownGenerator/MarkdownOptions/MarkdownResult` re-exports in `graph_crawler.shared.utils` are lazy.
317
+ `MarkdownPlugin` feeds the already-parsed Lexbor tree to html2md-clean 0.5 (`generate_from_tree`) —
318
+ one parse per page instead of 2–4. `import graph_crawler` no longer loads bs4/lxml.
319
+
320
+ - **Dependency map**. Core is now 10 packages: `requests`,
321
+ `httpx`, `pydantic-settings`, `pybloom-live`, `fastapi`, `tenacity`, `stop-words`, `tiktoken`,
322
+ `markdown-it-py` removed from `[project].dependencies`. New extras: `browser` (`playwright` kept as alias),
323
+ `server` (fastapi/uvicorn/websockets), `text` (tiktoken/stop-words), `captcha`; `markdown` also pulls
324
+ `markdown-it-py`; `all` is recursive. Extras `cloudscraper` and `undetected-sync` dropped.
325
+ Extra-gated imports are lazy and fail fast with `requires extra '<name>'`; `transport.PlaywrightDriver/
326
+ RequestsDriver/CloudscraperDriver/RequestsSessionAdapter` are lazy re-exports (ImportError instead of `None`).
327
+ `CrawlerSettings` keeps `GC_*`/`__`/`.env` without pydantic-settings; `CrawlerConfig` is a plain `BaseModel`.
328
+
329
+ - **Transport cleanup**. Deleted: sync drivers
330
+ (`RequestsDriver`, `CloudscraperDriver`, `UndetectedChromeDriver`, `BotasaurusDriver`, `BaseSyncDriver`),
331
+ `AsyncDriverHTTP2` (httpx), `AsyncCloudscraperDriver`, `tls_client.py`, `StealthHTTPDriver`,
332
+ `session_manager/session_adapters/session_protocol`, `shared/utils/captcha_bypass.py`,
333
+ `shared/utils/proxy_manager.py`, packages `transport/http` and `transport/browser`.
334
+ `DriverType` is now `aiohttp | tls | playwright | nodriver | escalating` (+ `asyncio` alias);
335
+ strings `http`/`async`/`asyncio` → `aiohttp` and `stealth`/`curl_cffi` → `tls` are accepted for one
336
+ release with `DeprecationWarning`. One `AsyncDriver` (former `driver_adaptive.py` is now
337
+ `async_http/driver.py`); request hints (`referer`, `extra_headers`, `cookies`) are honoured.
338
+ `requests` is gone from the package: proxy health-check, CAPTCHA solvers/bypass and `SitemapParser`
339
+ use aiohttp (`SitemapParser.parse_sitemap/parse_from_robots` are `asyncio.run` wrappers,
340
+ `http_client=` is deprecated and ignored). `BloomFilter` is pure-python (xxhash) — `pybloom-live`
341
+ no longer needed.
342
+ `import graph_crawler` no longer loads any extra (guarded by `tests/unit/test_import_surface.py`), 3.8 s → 1.7 s here.
343
+ `shared/constants.py` no longer imports aiohttp — `br`/`zstd` are advertised
344
+ by `transport.compression.runtime_browser_headers()` only when the runtime can decode them;
345
+ one driver registry — `application.services.driver_factory` delegates to
346
+ `transport.factory.DriverFactory` (`register_factory`, `registered_names`); `SitemapParser(driver=)`
347
+ fetches robots.txt/sitemaps through the crawl `IDriver` (same tier chain), `SitemapSpider` passes its
348
+ driver, aiohttp is used directly only for binary `.gz`; `tests/transport/test_all_drivers_report_redirects.py`
349
+ is an `IDriver` acceptance matrix (aiohttp / tls / fake playwright / fake nodriver / escalating).
350
+
351
+ - **Escalation**: `EscalationPolicy.reprobe_interval` (5 min) —
352
+ one request per interval re-probes tier 0 for a host remembered on a higher tier (no herd of browser
353
+ re-escalations after TTL); `EscalationPolicy.max_hosts` (10k) — `HostTierMemory` is an LRU and drops
354
+ per-host locks together with entries. In strict mode (`GC_ENGINE_STRICT`) an `ImportError` raised _during_
355
+ `fetch` (lazy browser start without the SDK) now propagates instead of being turned into a network error.
356
+
357
+ - **`extras` contract persisted.** New
358
+ `FetchResponse.fetch_provenance()` / `FETCH_EXTRAS_KEYS`: a JSON-safe slice
359
+ (`bot_block_status, channel, driver, engine, escalations` + `escalation_reason`; cookies/impersonate dropped).
360
+ `NodeScanner` stores it in `node.metadata["fetch"]` for every response, including blocked/error ones, so it
361
+ survives JSON/SQLite/MongoDB/PostgreSQL storage. Contract test `tests/transport/test_extras_contract.py`.
362
+
363
+ ### Fixed
364
+
365
+ - Transport `extras` (`bot_block_status`, tier, escalations) were dropped after fetch and never reached the
366
+ node or storage; for blocked pages nothing was transferred at all.
367
+ - `SmartPageFinder` read `html_tree.text` as a property; with Lexbor it is a method — page text was
368
+ silently dropped.
369
+ - `AsyncUndetectedDriver` accepts a plain `dict` config (`AsyncUndetectedConfig.from_mapping`) — building
370
+ the `nodriver` tier through `DriverFactory.create(DriverType.NODRIVER, config={...})` (as `EscalatingDriver`
371
+ does) raised `AttributeError`.
372
+
373
+ ## 5.2.0 — 2026-06
374
+
375
+ ### Added
376
+
377
+ - `infrastructure/transport/escalation.py`: `classify_block()` (Cloudflare / Akamai / DataDome /
378
+ PerimeterX / Incapsula markers, 403/429/503, empty 200), `EscalationPolicy`, `EscalationTier`,
379
+ `EscalatingDriver` — chain http → tls → browser → undetected with `max_tier`.
380
+ `driver="escalating"` works in `crawl()` / `async_crawl()` / `Crawler` / CLI.
381
+ - `HostTierMemory`: adaptive per-host tier memory — TTL from the moment of decision
382
+ (`GC_TIER_TTL`, default 1200 s), invalidation when the remembered tier gets blocked,
383
+ one escalation per host at a time (per-host lock). Per process.
384
+ - Strict engine mode: `GC_ENGINE_STRICT=1`, `{"browser_engine": {"strict": True}}` or
385
+ `driver_config={"engine_strict": True}` — `ImportError` instead of a silent fallback
386
+ `cloakbrowser → patchright → playwright` or a skipped escalation tier.
387
+ - Browser engine registry in `playwright/engine.py`: `register_engine()`, `resolve_engine()`,
388
+ `registered_engines()`. Built-in engines `cloakbrowser` → `patchright` → `playwright` with
389
+ automatic fail-open. `GC_BROWSER_ENGINE` env selects the engine when config has none.
390
+ `PlaywrightBrowserEngine.effective_name` / `fallback_reason`.
391
+ - `FetchResponse.extras` contract: `bot_block_status`, `channel`, `driver`, `engine`, `escalations`.
392
+ - `DriverType.TLS`, `NODRIVER`, `UNDETECTED`, `BOTASAURUS`, `ESCALATING`; `DriverFactory.create()`
393
+ accepts extra constructor kwargs (`policy=`).
394
+ - Extras: `tls`, `stealth`, `cloak`, `undetected`, `undetected-sync`, `antidetect`, `cloudscraper`, `system`.
395
+ - `README.md`, `CHANGELOG.md`.
396
+
397
+ ### Changed
398
+
399
+ - `normalize_protocol` defaults to `False`: `http://` and `https://` are different URLs.
400
+ The crawler follows the real redirect instead of rewriting the scheme itself, so
401
+ http-only hosts stay reachable. Enable it explicitly to merge both schemes on dedup.
402
+ - `Graph.handle_redirect()` stores the alias as the real `Location` the server sent
403
+ (provenance); the normalized form is used only to find and merge nodes.
404
+ - Single `DriverType` enum (`transport/base.py`); `factory.py` re-exports it.
405
+ - `cloudscraper` moved from required dependencies to extra `cloudscraper`.
406
+ - `psutil` is optional (`system` extra); `MemoryGuard` imports it lazily.
407
+ - `requires-python = ">=3.11"` (upper bound removed; classifiers 3.11–3.14).
408
+ - `pytest` runs offline by default (`-m 'not manual'`, no coverage in `addopts`).
409
+ Network / real-site tests live in `tests/manual/` and run with `pytest -m manual tests/manual`.
410
+ - Project URLs point to the GitLab repository.
411
+
412
+ ### Fixed
413
+
414
+ - `pooled_driver`: bounded walk over `redirected_from` (infinite loop on objects without a
415
+ `None` terminator); cookies are no longer added twice to a fresh browser.
416
+ - Tests synced with the code: redirect aliases, `html2md-clean` 0.4.0 API, `crawl_coordinator`
417
+ `per_host_max_in_flight`, `.gitignore` lookup at the repository root, `tools/db_cleanup.py`
418
+ CLI allow-listed for `print`. Playwright fake tests skip when `playwright` is not installed.
419
+
420
+ ### Removed
421
+
422
+ - `tests/345.py`, `tests/ДОДАТКОВІ_ТЕСТИ.py`, `tests/manual_4a_games_test.py`, `tests/google_maps_results.json`.
423
+ - `EXTRACTION_AUDIT.md` and other analysis / plan documents that described work, not the code.
424
+ - `graph_crawler/data/ARCHITECTURE.md`, `MIGRATION_50_STEPS.md`, `REFACTORING_PLAN.md`, `mkdocs.yml`
425
+ (finished plans / config without content).
426
+
427
+ ## 5.1.0
428
+
429
+ Previous release (sync-first API, Playwright pool, adaptive HTTP drivers, storage backends).
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024 GraphCrawler Team
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,16 @@
1
+ include README.md
2
+ include LICENSE
3
+ include CHANGELOG.md
4
+ include pyproject.toml
5
+ include graph_crawler/py.typed
6
+
7
+ recursive-include graph_crawler/native *.pyx
8
+ include graph_crawler/native/setup.py
9
+
10
+ prune tests
11
+ global-exclude __pycache__
12
+ global-exclude *.py[cod]
13
+ global-exclude *.so
14
+ global-exclude *.pyd
15
+ global-exclude *.c
16
+ global-exclude .DS_Store