ph-api-scraper 3.4.0

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 (63) hide show
  1. package/.cache/replit/env/latest +63 -0
  2. package/.cache/replit/env/latest.json +1 -0
  3. package/.cache/replit/modules/nodejs-20.res +1 -0
  4. package/.cache/replit/modules/replit-rtld-loader.res +1 -0
  5. package/.cache/replit/modules/replit.res +1 -0
  6. package/.cache/replit/modules.stamp +0 -0
  7. package/.cache/replit/nix/dotreplitenv.json +1 -0
  8. package/.cache/replit/toolchain.json +1 -0
  9. package/.cache/typescript/5.8/package.json +1 -0
  10. package/.codeclimate.yml +4 -0
  11. package/.config/configstore/update-notifier-ava.json +4 -0
  12. package/.gitattributes +1 -0
  13. package/.github/ISSUE_TEMPLATE/bug_report.md +17 -0
  14. package/.github/ISSUE_TEMPLATE/feature_request.md +11 -0
  15. package/.github/ISSUE_TEMPLATE/questions.md +12 -0
  16. package/.local/state/replit/agent/.agent_state_6fa31f60be98e5d6fb0c67811b64cd555a363f53.bin +0 -0
  17. package/.local/state/replit/agent/.agent_state_f567f1857ae17f372d3c99c01eb473389bc6019d.bin +0 -0
  18. package/.local/state/replit/agent/.agent_state_main.bin +0 -0
  19. package/.local/state/replit/agent/.latest.json +1 -0
  20. package/.local/state/replit/agent/repl_state.bin +0 -0
  21. package/.replit +29 -0
  22. package/.travis.yml +6 -0
  23. package/.xo-config.js +8 -0
  24. package/LICENSE +21 -0
  25. package/README.md +378 -0
  26. package/example.js +31 -0
  27. package/imgs/pornhub-api.jpg +0 -0
  28. package/package.json +51 -0
  29. package/replit.md +48 -0
  30. package/src/constants/consts_global.js +95 -0
  31. package/src/constants/consts_model.js +23 -0
  32. package/src/constants/consts_page.js +83 -0
  33. package/src/constants/consts_queries.js +11 -0
  34. package/src/constants/consts_sanitizer.js +14 -0
  35. package/src/constants/consts_scrap.js +10 -0
  36. package/src/constants/consts_search.js +22 -0
  37. package/src/constants/consts_search_gifs.js +15 -0
  38. package/src/constants/consts_search_pornstars.js +25 -0
  39. package/src/constants/consts_search_videos.js +29 -0
  40. package/src/helpers/utils_global.js +36 -0
  41. package/src/helpers/utils_sanitizer.js +144 -0
  42. package/src/helpers/utils_scrap.js +65 -0
  43. package/src/index.js +101 -0
  44. package/src/model.js +44 -0
  45. package/src/packages/postinstall.js +1 -0
  46. package/src/page.js +66 -0
  47. package/src/search.js +31 -0
  48. package/src/utils.js +197 -0
  49. package/tests/datas/page_model.html +6056 -0
  50. package/tests/datas/page_pornhub.html +7809 -0
  51. package/tests/datas/page_pornhub_exception.html +7699 -0
  52. package/tests/datas/search_pornhub_aa_actor_1.html +4446 -0
  53. package/tests/datas/search_pornhub_aa_page_1.html +4440 -0
  54. package/tests/datas/search_pornhub_aa_page_2.html +4044 -0
  55. package/tests/datas/search_pornhub_doggy_gifs.html +3390 -0
  56. package/tests/dynamic/tests_page.js +104 -0
  57. package/tests/dynamic/tests_search.js +14 -0
  58. package/tests/dynamic/tests_video.js +22 -0
  59. package/tests/static/tests_model.js +76 -0
  60. package/tests/static/tests_page.js +107 -0
  61. package/tests/static/tests_search.js +59 -0
  62. package/tests/static/tests_utils.js +134 -0
  63. package/tests/static/tests_video.js +13 -0
@@ -0,0 +1,63 @@
1
+ declare -gx NIX_PATH=nixpkgs=/home/runner/.nix-defexpr/channels/nixpkgs-stable-25_05:/home/runner/.nix-defexpr/channels
2
+ declare -gx REPL_OWNER_ID=52054157
3
+ declare -gx REPLIT_DOMAINS=6a0d1164-5317-4546-a78a-12f30dccb699-00-fidfz6x89mty.sisko.replit.dev
4
+ declare -gx REPL_OWNER=jermain1659
5
+ declare -gx REPLIT_ENVIRONMENT=production
6
+ declare -gx REPLIT_CONTAINER=gcr.io/marine-cycle-160323/repl-base:3c526f0870c482ef04b1ca6073a0d578ba34e814
7
+ declare -gx REPL_ID=6a0d1164-5317-4546-a78a-12f30dccb699
8
+ declare -gx GIT_EDITOR=replit-git-editor
9
+ declare -gx REPLIT_RTLD_LOADER=1
10
+ declare -gx LD_AUDIT=/nix/store/6y0zqxaf220r36b74hwsq9m2b2av3lw7-replit_rtld_loader-1/rtld_loader.so
11
+ declare -gx __EGL_VENDOR_LIBRARY_FILENAMES=/nix/store/l4myp7qn0q9bqgmkqq4vnnii22ql1r68-mesa-25.0.7/share/glvnd/egl_vendor.d/50_mesa.json
12
+ declare -gx REPLIT_SUBCLUSTER=interactive
13
+ declare -gx REPLIT_BASHRC=/nix/store/lsgsb0ar7rdwa09d1z2dnfjh4188pddk-replit-bashrc/bashrc
14
+ declare -gx REPLIT_GITSAFE_EXISTING_REPLS_ENABLED=false
15
+ declare -gx REPL_SLUG=workspace
16
+ declare -gx NIX_PS1='\[\033[01;34m\]\w\[\033[00m\]\$ '
17
+ declare -gx NIXPKGS_ALLOW_UNFREE=1
18
+ declare -gx REPLIT_RIPPKGS_INDICES=/nix/store/cg6q7dm7h9jp20vwj79ahnbsd9cs6iay-rippkgs-indices
19
+ declare -gx LIBGL_DRIVERS_PATH=/nix/store/l4myp7qn0q9bqgmkqq4vnnii22ql1r68-mesa-25.0.7/lib/dri
20
+ declare -gx REPLIT_PID1_FLAG_PREEVALED_SYSPKGS=1
21
+ declare -gx PGDATABASE=heliumdb
22
+ declare -gx CONNECTORS_HOSTNAME=connectors.replit.com
23
+ declare -gx REPLIT_PID1_VERSION=0.0.0-fc2aec4
24
+ declare -gx REPLIT_GITSAFE_ENABLED=true
25
+ declare -gx REPL_HOME=/home/runner/workspace
26
+ declare -gx PGPASSWORD=password
27
+ declare -gx COLORTERM=truecolor
28
+ declare -gx npm_config_prefix=/home/runner/workspace/.config/npm/node_global
29
+ declare -gx XDG_DATA_HOME=/home/runner/workspace/.local/share
30
+ declare -gx REPL_PUBKEYS='{"crosis-ci":"7YlpcYh82oR9NSTtSYtR5jDL4onNzCGJGq6b+9CuZII=","crosis-ci:1":"7YlpcYh82oR9NSTtSYtR5jDL4onNzCGJGq6b+9CuZII=","crosis-ci:latest":"7YlpcYh82oR9NSTtSYtR5jDL4onNzCGJGq6b+9CuZII=","prod":"tGsjlu/BJvWTgvMaX7acuUb7AO1dXOrRiuk7y083RFE=","prod:1":"tGsjlu/BJvWTgvMaX7acuUb7AO1dXOrRiuk7y083RFE=","prod:3":"9+MCOSHQSQlcodXoot8dC8NLhc862nLkx1/VMsbY2h8=","prod:4":"8uGN+vfszlnV93/HCSHlVLG0xddMlPkir1Ni4JKT4+w=","prod:5":"9+MCOSHQSQlcodXoot8dC8NLhc862nLkx1/VMsbY2h8=","prod:latest":"tGsjlu/BJvWTgvMaX7acuUb7AO1dXOrRiuk7y083RFE=","vault-goval-token":"D5jJoMx1Ml54HM92NLgXl+MzptwDqbSsfyFG6f52g9E=","vault-goval-token:1":"D5jJoMx1Ml54HM92NLgXl+MzptwDqbSsfyFG6f52g9E=","vault-goval-token:latest":"D5jJoMx1Ml54HM92NLgXl+MzptwDqbSsfyFG6f52g9E="}'
31
+ declare -gx XDG_CONFIG_HOME=/home/runner/workspace/.config
32
+ declare -gx XDG_DATA_DIRS=/nix/store/cmbvpai7z0fqh6ljlgbbdcsx873ilngl-replit-runtime-path/share
33
+ declare -gx GIT_ASKPASS=replit-git-askpass
34
+ read -r _new_path <<< "/nix/store/djy8g4cghlw19fmy6zblim1waxkr7mf2-npx/bin:/home/runner/workspace/.config/npm/node_global/bin:/home/runner/workspace/node_modules/.bin:/nix/store/8y4ls7z2sfxbq6ch3yp45l28p29qswvx-nodejs-20.19.3-wrapped/bin:/nix/store/nj22dzxzzx4m80lfa91fzqh8k9lvwigw-bun-1.2.16/bin:/nix/store/pciji08qkvcg3191yykpfipdcbbic9k5-pnpm-10.12.4/bin:/nix/store/6mzbvyzh4dfgfab6lciclji7awp9w3c4-yarn-1.22.22/bin:/nix/store/gvg9vrp821nmnyf9pxig6pss1sjywd5w-prettier-3.5.3/bin:/nix/store/d6q6v6zg2plfxig3vnkx7fc1iazjybhy-pid1/bin:/nix/store/cmbvpai7z0fqh6ljlgbbdcsx873ilngl-replit-runtime-path/bin:/home/runner/.nix-profile/bin:/home/runner/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
35
+ #PATH=/nix/store/djy8g4cghlw19fmy6zblim1waxkr7mf2-npx/bin:/home/runner/workspace/.config/npm/node_global/bin:/home/runner/workspace/node_modules/.bin:/nix/store/8y4ls7z2sfxbq6ch3yp45l28p29qswvx-nodejs-20.19.3-wrapped/bin:/nix/store/nj22dzxzzx4m80lfa91fzqh8k9lvwigw-bun-1.2.16/bin:/nix/store/pciji08qkvcg3191yykpfipdcbbic9k5-pnpm-10.12.4/bin:/nix/store/6mzbvyzh4dfgfab6lciclji7awp9w3c4-yarn-1.22.22/bin:/nix/store/gvg9vrp821nmnyf9pxig6pss1sjywd5w-prettier-3.5.3/bin:/nix/store/d6q6v6zg2plfxig3vnkx7fc1iazjybhy-pid1/bin:/nix/store/cmbvpai7z0fqh6ljlgbbdcsx873ilngl-replit-runtime-path/bin:/home/runner/.nix-profile/bin:/home/runner/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
36
+ if [ -e "/run/replit/env/last" ]; then read -r _last_path < <(\grep '^#PATH=' /run/replit/env/last | cut -f 2 -d =); fi
37
+ _user_components="$(\tr : $'\n' <<< "${PATH:-}" |\grep -xv -f <(\tr : $'\n' <<< "${_last_path}") |\tr $'\n' :)"
38
+ declare -gx PATH="${_user_components}${_new_path}"
39
+ declare -gx LANG=en_US.UTF-8
40
+ declare -gx HOSTNAME=44234388b877
41
+ declare -gx REPLIT_GITSAFE_NEW_REPLS_ENABLED=true
42
+ declare -gx DATABASE_URL='postgresql://postgres:password@helium/heliumdb?sslmode=disable'
43
+ declare -gx REPLIT_HELIUM_ENABLED=true
44
+ declare -gx PROMPT_DIRTRIM=2
45
+ declare -gx GLIBC_TUNABLES=glibc.rtld.optional_static_tls=10000
46
+ declare -gx PGHOST=helium
47
+ declare -gx REPLIT_NIX_CHANNEL=stable-25_05
48
+ declare -gx LOCALE_ARCHIVE=/usr/lib/locale/locale-archive
49
+ declare -gx DOCKER_CONFIG=/home/runner/workspace/.config/docker
50
+ declare -gx REPLIT_LD_AUDIT=/nix/store/6y0zqxaf220r36b74hwsq9m2b2av3lw7-replit_rtld_loader-1/rtld_loader.so
51
+ declare -gx HOME=/home/runner
52
+ declare -gx DISPLAY=:0
53
+ declare -gx REPL_IMAGE=gcr.io/marine-cycle-160323/nix:bf8590a3e2f0a8b70b7ca175eeed9074dffbfca9
54
+ declare -gx REPLIT_DEV_DOMAIN=6a0d1164-5317-4546-a78a-12f30dccb699-00-fidfz6x89mty.sisko.replit.dev
55
+ declare -gx XDG_CACHE_HOME=/home/runner/workspace/.cache
56
+ declare -gx REPLIT_CONNECTORS_HOSTNAME=connectors.replit.com
57
+ declare -gx USER=runner
58
+ declare -gx REPLIT_CLI=/nix/store/fram2jlap629zmyg0whbwzwqarph4i7h-replit-cli-0.0.1/bin/replit
59
+ declare -gx NIX_PROFILES='/nix/var/nix/profiles/default /home/runner/.nix-profile'
60
+ declare -gx PGUSER=postgres
61
+ declare -gx REPLIT_CLUSTER=sisko
62
+ declare -gx PGPORT=5432
63
+ declare -gx REPL_LANGUAGE=nix
@@ -0,0 +1 @@
1
+ {"environment":{"COLORTERM":"truecolor","CONNECTORS_HOSTNAME":"connectors.replit.com","DATABASE_URL":"postgresql://postgres:password@helium/heliumdb?sslmode=disable","DISPLAY":":0","DOCKER_CONFIG":"/home/runner/workspace/.config/docker","GIT_ASKPASS":"replit-git-askpass","GIT_EDITOR":"replit-git-editor","GLIBC_TUNABLES":"glibc.rtld.optional_static_tls=10000","HOME":"/home/runner","HOSTNAME":"44234388b877","LANG":"en_US.UTF-8","LD_AUDIT":"/nix/store/6y0zqxaf220r36b74hwsq9m2b2av3lw7-replit_rtld_loader-1/rtld_loader.so","LIBGL_DRIVERS_PATH":"/nix/store/l4myp7qn0q9bqgmkqq4vnnii22ql1r68-mesa-25.0.7/lib/dri","LOCALE_ARCHIVE":"/usr/lib/locale/locale-archive","NIXPKGS_ALLOW_UNFREE":"1","NIX_PATH":"nixpkgs=/home/runner/.nix-defexpr/channels/nixpkgs-stable-25_05:/home/runner/.nix-defexpr/channels","NIX_PROFILES":"/nix/var/nix/profiles/default /home/runner/.nix-profile","NIX_PS1":"\\[\\033[01;34m\\]\\w\\[\\033[00m\\]\\$ ","PATH":"/nix/store/djy8g4cghlw19fmy6zblim1waxkr7mf2-npx/bin:/home/runner/workspace/.config/npm/node_global/bin:/home/runner/workspace/node_modules/.bin:/nix/store/8y4ls7z2sfxbq6ch3yp45l28p29qswvx-nodejs-20.19.3-wrapped/bin:/nix/store/nj22dzxzzx4m80lfa91fzqh8k9lvwigw-bun-1.2.16/bin:/nix/store/pciji08qkvcg3191yykpfipdcbbic9k5-pnpm-10.12.4/bin:/nix/store/6mzbvyzh4dfgfab6lciclji7awp9w3c4-yarn-1.22.22/bin:/nix/store/gvg9vrp821nmnyf9pxig6pss1sjywd5w-prettier-3.5.3/bin:/nix/store/d6q6v6zg2plfxig3vnkx7fc1iazjybhy-pid1/bin:/nix/store/cmbvpai7z0fqh6ljlgbbdcsx873ilngl-replit-runtime-path/bin:/home/runner/.nix-profile/bin:/home/runner/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin","PGDATABASE":"heliumdb","PGHOST":"helium","PGPASSWORD":"password","PGPORT":"5432","PGUSER":"postgres","PROMPT_DIRTRIM":"2","REPLIT_BASHRC":"/nix/store/lsgsb0ar7rdwa09d1z2dnfjh4188pddk-replit-bashrc/bashrc","REPLIT_CLI":"/nix/store/fram2jlap629zmyg0whbwzwqarph4i7h-replit-cli-0.0.1/bin/replit","REPLIT_CLUSTER":"sisko","REPLIT_CONNECTORS_HOSTNAME":"connectors.replit.com","REPLIT_CONTAINER":"gcr.io/marine-cycle-160323/repl-base:3c526f0870c482ef04b1ca6073a0d578ba34e814","REPLIT_DEV_DOMAIN":"6a0d1164-5317-4546-a78a-12f30dccb699-00-fidfz6x89mty.sisko.replit.dev","REPLIT_DOMAINS":"6a0d1164-5317-4546-a78a-12f30dccb699-00-fidfz6x89mty.sisko.replit.dev","REPLIT_ENVIRONMENT":"production","REPLIT_GITSAFE_ENABLED":"true","REPLIT_GITSAFE_EXISTING_REPLS_ENABLED":"false","REPLIT_GITSAFE_NEW_REPLS_ENABLED":"true","REPLIT_HELIUM_ENABLED":"true","REPLIT_LD_AUDIT":"/nix/store/6y0zqxaf220r36b74hwsq9m2b2av3lw7-replit_rtld_loader-1/rtld_loader.so","REPLIT_NIX_CHANNEL":"stable-25_05","REPLIT_PID1_FLAG_PREEVALED_SYSPKGS":"1","REPLIT_PID1_VERSION":"0.0.0-fc2aec4","REPLIT_RIPPKGS_INDICES":"/nix/store/cg6q7dm7h9jp20vwj79ahnbsd9cs6iay-rippkgs-indices","REPLIT_RTLD_LOADER":"1","REPLIT_SUBCLUSTER":"interactive","REPL_HOME":"/home/runner/workspace","REPL_ID":"6a0d1164-5317-4546-a78a-12f30dccb699","REPL_IMAGE":"gcr.io/marine-cycle-160323/nix:bf8590a3e2f0a8b70b7ca175eeed9074dffbfca9","REPL_LANGUAGE":"nix","REPL_OWNER":"jermain1659","REPL_OWNER_ID":"52054157","REPL_PUBKEYS":"{\"crosis-ci\":\"7YlpcYh82oR9NSTtSYtR5jDL4onNzCGJGq6b+9CuZII=\",\"crosis-ci:1\":\"7YlpcYh82oR9NSTtSYtR5jDL4onNzCGJGq6b+9CuZII=\",\"crosis-ci:latest\":\"7YlpcYh82oR9NSTtSYtR5jDL4onNzCGJGq6b+9CuZII=\",\"prod\":\"tGsjlu/BJvWTgvMaX7acuUb7AO1dXOrRiuk7y083RFE=\",\"prod:1\":\"tGsjlu/BJvWTgvMaX7acuUb7AO1dXOrRiuk7y083RFE=\",\"prod:3\":\"9+MCOSHQSQlcodXoot8dC8NLhc862nLkx1/VMsbY2h8=\",\"prod:4\":\"8uGN+vfszlnV93/HCSHlVLG0xddMlPkir1Ni4JKT4+w=\",\"prod:5\":\"9+MCOSHQSQlcodXoot8dC8NLhc862nLkx1/VMsbY2h8=\",\"prod:latest\":\"tGsjlu/BJvWTgvMaX7acuUb7AO1dXOrRiuk7y083RFE=\",\"vault-goval-token\":\"D5jJoMx1Ml54HM92NLgXl+MzptwDqbSsfyFG6f52g9E=\",\"vault-goval-token:1\":\"D5jJoMx1Ml54HM92NLgXl+MzptwDqbSsfyFG6f52g9E=\",\"vault-goval-token:latest\":\"D5jJoMx1Ml54HM92NLgXl+MzptwDqbSsfyFG6f52g9E=\"}","REPL_SLUG":"workspace","USER":"runner","XDG_CACHE_HOME":"/home/runner/workspace/.cache","XDG_CONFIG_HOME":"/home/runner/workspace/.config","XDG_DATA_DIRS":"/nix/store/cmbvpai7z0fqh6ljlgbbdcsx873ilngl-replit-runtime-path/share","XDG_DATA_HOME":"/home/runner/workspace/.local/share","__EGL_VENDOR_LIBRARY_FILENAMES":"/nix/store/l4myp7qn0q9bqgmkqq4vnnii22ql1r68-mesa-25.0.7/share/glvnd/egl_vendor.d/50_mesa.json","npm_config_prefix":"/home/runner/workspace/.config/npm/node_global"}}
@@ -0,0 +1 @@
1
+ {"type":"resolve","resolvedModuleId":"nodejs-20","inputHash":"","resolutionPath":["nodejs-20"],"error":"","Changed":true}
@@ -0,0 +1 @@
1
+ {"type":"resolve","resolvedModuleId":"replit-rtld-loader","inputHash":"","resolutionPath":["replit-rtld-loader"],"error":"","Changed":true}
@@ -0,0 +1 @@
1
+ {"type":"resolve","resolvedModuleId":"replit","inputHash":"","resolutionPath":["replit"],"error":"","Changed":true}
File without changes
@@ -0,0 +1 @@
1
+ {"channel":"stable-25_05","channel_nix_path":"/nix/store/nycikbxm6f1z09aq81jcrcgbsfs595bh-nixpkgs-stable-25_05-25.05.tar.gz/nixpkgs-stable-25_05","env":null,"packages":null}
@@ -0,0 +1 @@
1
+ {"runs":[{"id":"module:nodejs-20/runner:nodeJS", "name":"Node.js", "fileParam":true, "language":"javascript", "fileTypeAttrs":{}, "displayVersion":"20.19.3", "run":{"command":{"args":["sh", "-c", "/nix/store/8y4ls7z2sfxbq6ch3yp45l28p29qswvx-nodejs-20.19.3-wrapped/bin/node $file"]}}, "defaultEntrypoints":["index.js", "main.js"]}], "debuggers":[{"id":"module:nodejs-20/debugger:nodeDAP", "name":"Node DAP", "fileParam":true, "language":"javascript", "fileTypeAttrs":{}}], "languageServers":[{"id":"module:replit/languageServer:dotreplit-lsp", "name":".replit LSP", "language":"dotreplit", "fileTypeAttrs":{}, "config":{"startCommand":{"args":["sh", "-c", "/nix/store/25rasmkzxdlxf3w5rasswn4ypm7ibw9l-taplo-0.patched/bin/taplo lsp -c /nix/store/5ill1byfvfxm5mdi58w30rq5rmmxa2xv-taplo-config.toml stdio"]}}}, {"id":"module:nodejs-20/languageServer:typescript-language-server", "name":"TypeScript Language Server", "language":"javascript", "fileTypeAttrs":{"extensions":[".js", ".jsx", ".ts", ".tsx", ".mjs", ".mts", ".cjs", ".cts", ".es6", ".json"]}, "config":{"startCommand":{"args":["sh", "-c", "/nix/store/rb3xzs9lwfnlz6f3ij7b3yqy6xdw9zj9-typescript-language-server-4.3.3/bin/typescript-language-server --stdio"]}, "initializationOptionsJson":"{\"tsserver\":{\"fallbackPath\":\"/nix/store/jm6f250skx57gnfbisb8kkqgkc0ph9p5-typescript-5.8.3/lib/node_modules/typescript/lib\"}}"}, "displayVersion":"4.3.3"}], "packagers":[{"id":"module:nodejs-20/packager:upmNodejs", "name":"Node.js packager (npm, yarn, pnpm, bun)", "language":"nodejs", "packageSearch":true, "guessImports":true}], "formatters":[{"id":"module:nodejs-20/formatter:prettier", "name":"Prettier", "startCommand":{"args":["/nix/store/q8dvw6s652rsnzxpbfb2glyvnpb2xb02-run-prettier/bin/run-prettier"], "lifecycle":"STDIN", "splitStderr":true}, "fileTypeAttrs":{"extensions":[".js", ".jsx", ".ts", ".tsx", ".json", ".html"]}, "displayVersion":"3.5.3", "supportsRangeFormatting":true}, {"id":"module:nodejs-20/languageServer:typescript-language-server", "name":"TypeScript Language Server", "fileTypeAttrs":{"extensions":[".js", ".jsx", ".ts", ".tsx", ".mjs", ".mts", ".cjs", ".cts", ".es6", ".json"]}, "displayVersion":"4.3.3"}, {"id":"module:replit/languageServer:dotreplit-lsp", "name":".replit LSP", "fileTypeAttrs":{}}]}
@@ -0,0 +1 @@
1
+ {"private":true,"dependencies":{"types-registry":"^0.1.752"},"devDependencies":{"@types/cssstyle":"^2.2.4","@types/data-urls":"^3.0.4","@types/domexception":"^4.0.3","@types/duplexer3":"^0.1.5","@types/ejs":"^3.1.5","@types/html-encoding-sniffer":"^3.0.2","@types/jsdom":"^27.0.0","@types/node":"^25.0.3","@types/object-assign":"^4.0.33","@types/page":"^1.11.9","@types/uglify-js":"^3.17.5","@types/universalify":"^1.0.3","@types/url-parse":"^1.4.11","@types/url-parse-lax":"^5.0.2","@types/w3c-hr-time":"^1.0.2","@types/w3c-xmlserializer":"^2.0.4","@types/webidl-conversions":"^7.0.3","@types/whatwg-encoding":"^2.0.3","@types/whatwg-mimetype":"^3.0.2","@types/whatwg-url":"^13.0.0","@types/xo":"^0.39.9"}}
@@ -0,0 +1,4 @@
1
+ exclude_patterns:
2
+ - "node_modules/"
3
+ - "src/constants/"
4
+ - "tests/"
@@ -0,0 +1,4 @@
1
+ {
2
+ "optOut": false,
3
+ "lastUpdateCheck": 1767035702522
4
+ }
package/.gitattributes ADDED
@@ -0,0 +1 @@
1
+ *.html linguist-detectable=false
@@ -0,0 +1,17 @@
1
+ ---
2
+ name: Bug report
3
+ about: Create a bug you want to see fixed
4
+ title: "[BUG] title"
5
+ labels: bug
6
+ assignees: JustalK
7
+
8
+ ---
9
+
10
+ **Describe the bug**
11
+ A clear description of the bug
12
+
13
+ **To Reproduce**
14
+ If applicable, describe the process for reproducing the bug
15
+
16
+ **Screenshots**
17
+ If applicable, add screenshots to help explain your problem.
@@ -0,0 +1,11 @@
1
+ ---
2
+ name: Feature request
3
+ about: Suggest a new feature
4
+ title: "[FEATURE]"
5
+ labels: enhancement
6
+ assignees: JustalK
7
+
8
+ ---
9
+
10
+ **Describe the new feature you would like to see**
11
+ A clear description of the new feature
@@ -0,0 +1,12 @@
1
+ ---
2
+ name: Questions
3
+ about: Do you want to ask me a question about this project ?
4
+ title: Question
5
+ labels: question
6
+ assignees: JustalK
7
+
8
+ ---
9
+
10
+ Hello Justalk,
11
+
12
+ **Here, you can ask any question about my package, about the code or how to use it.**
@@ -0,0 +1 @@
1
+ {"latest": "main"}
package/.replit ADDED
@@ -0,0 +1,29 @@
1
+ modules = ["nodejs-20"]
2
+ [agent]
3
+ expertMode = true
4
+
5
+ [nix]
6
+ channel = "stable-25_05"
7
+
8
+ [workflows]
9
+ runButton = "Project"
10
+
11
+ [[workflows.workflow]]
12
+ name = "Project"
13
+ mode = "parallel"
14
+ author = "agent"
15
+
16
+ [[workflows.workflow.tasks]]
17
+ task = "workflow.run"
18
+ args = "Run Example"
19
+
20
+ [[workflows.workflow]]
21
+ name = "Run Example"
22
+ author = "agent"
23
+
24
+ [[workflows.workflow.tasks]]
25
+ task = "shell.exec"
26
+ args = "node example.js"
27
+
28
+ [workflows.workflow.metadata]
29
+ outputType = "console"
package/.travis.yml ADDED
@@ -0,0 +1,6 @@
1
+ language: node_js
2
+ node_js:
3
+ - 15
4
+ - 14
5
+ - 12
6
+ after_success: npm run coverage
package/.xo-config.js ADDED
@@ -0,0 +1,8 @@
1
+ module.exports = {
2
+ "esnext": true,
3
+ "rules" : {
4
+ "camelcase": 0,
5
+ "no-unused-vars": 0,
6
+ "unicorn/filename-case": 0
7
+ }
8
+ }
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) Justal Kevin
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.
package/README.md ADDED
@@ -0,0 +1,378 @@
1
+ ![Alt text](/imgs/pornhub-api.jpg?raw=true "pornhub api")
2
+
3
+ ![Last version npm](https://img.shields.io/npm/v/@justalk/pornhub-api.svg?style=flat-square)
4
+ ![Last version](https://img.shields.io/github/v/tag/justalk/pornhub-api.svg?style=flat-square)
5
+ [![Node version](https://img.shields.io/node/v/@justalk/pornhub-api.svg?style=flat-square)](https://www.npmjs.com/package/@justalk/pornhub-api)
6
+ [![Travis](https://img.shields.io/travis/com/justalk/pornhub-api.svg?style=flat-square)](https://travis-ci.com/github/JustalK/PORNHUB-API)
7
+ [![Coverage Status](https://coveralls.io/repos/github/JustalK/PORNHUB-API/badge.svg?branch=master&style=flat-square)](https://coveralls.io/github/JustalK/PORNHUB-API?branch=master)
8
+ ![Last version](https://img.shields.io/github/license/justalk/pornhub-api.svg?style=flat-square)
9
+ [![Maintainability Status](https://api.codeclimate.com/v1/badges/549f47de01e1ca98d830/maintainability)](https://codeclimate.com/github/JustalK/PORNHUB-API/maintainability)
10
+ [![XO code style](https://img.shields.io/badge/code_style-XO-5ed9c7.svg?style=flat-square)](https://github.com/xojs/xo)
11
+
12
+ ![Star the project](https://img.shields.io/github/stars/justalk/pornhub-api?style=social)
13
+
14
+ Powerful updated scraper for PornHub. Unlike others scrapers, it's working in 2020 October with their new website. It allows you to get any informations out of any page.
15
+
16
+ ### Installation
17
+
18
+ `npm install @justalk/pornhub-api`
19
+
20
+ or if you use yarn
21
+
22
+ `yarn add @justalk/pornhub-api --ignore-engines`
23
+
24
+ ### Short Examples
25
+
26
+ Scraping the title, pornstars and the download links of a page
27
+
28
+ ```js
29
+ const pornhub = require('@justalk/pornhub-api');
30
+ const url = 'https://www.pornhub.com/view_video.php?viewkey=ph56fc59c124c0c';
31
+ const video = await pornhub.page(url, ['title','pornstars','download_urls']);
32
+ ```
33
+
34
+ ### Features
35
+
36
+ - **Scraper:** Parse any page of pornhub : search page, model, video page...
37
+
38
+ - **Download links:** Get the download links in all the quality without registering
39
+
40
+ - **Search pagination:** This api can scrap multiple page at the same time
41
+
42
+ - **Search by different criteria:** Possibility to scrap different part of the site and to take advantage of the filter
43
+
44
+ - **Flexible:** The results are always return in a very specific javascrypt type making it easy to integrate to your need.
45
+
46
+ ### Scraping of a single video page pornhub
47
+
48
+ ```js
49
+ async page(url, options)
50
+ ```
51
+
52
+ | name | type | description | default |
53
+ | :--- | :---------- | :-------------------------- | :-------- |
54
+ | url | String | [Mandatory] url of the page | - |
55
+ | keys | Array | List of the keys | ['title'] |
56
+
57
+ <details>
58
+ <summary><b>Lists of options available for a search</b> (click to show)</summary>
59
+
60
+ | name of key | return type | description |
61
+ | :--- | :---------- | :--- |
62
+ | title | String | Title |
63
+ | description | String | Description |
64
+ | views | Number | Number total of views |
65
+ | up_votes | Number | Number of up vote |
66
+ | down_votes | Number | Number of down vote |
67
+ | percent | Number | Percent of up vote |
68
+ | author | String | Name of the uploader |
69
+ | author_subscriber | Number | Number of subscriber of the uploader |
70
+ | pornstars | Array | Names of the pornstars |
71
+ | categories | Array | List of the names of the categories |
72
+ | tags | Array | List of the names of the tags |
73
+ | production | String | Type of production |
74
+ | duration | Number | Duration in second |
75
+ | number_of_comment | Number | Total number of comments |
76
+ | thumbnail_url | String | Url of the thumbnail |
77
+ | upload_date | Date | Date of upload |
78
+ | download_urls | Object | List of download link by quality |
79
+ | comments | Object | List of comments with additionnals informations |
80
+ | related_videos | Object | List of related video with additionnals informations |
81
+
82
+ </details>
83
+
84
+ ### Scraping of a search page pornhub
85
+
86
+ ```js
87
+ async search(value, keys, options)
88
+ ```
89
+
90
+ | name | type | description |
91
+ | :------ | :----------------------------------------------- | :--------------------------------------- |
92
+ | value | String | value search in pornhub |
93
+ | keys | Array or String if there is only one option | List of the keys |
94
+ | options | Array | [OPTIONNAL] List of the optional options |
95
+
96
+ <details>
97
+ <summary><b>Lists of options available for a search</b> (click to show)</summary>
98
+
99
+ | name of options | return type | description | options | default |
100
+ | :-------------- | :---------- | :--------------------------------------------- | :----------------------- | :-------- |
101
+ | page | Number | Number of page to scraper | - | 1 |
102
+ | production | String | Type of production targeted | homemade, professional | - |
103
+ | min_duration | Number | Minimum number of minute of the video searched | 10, 20, 30 | - |
104
+ | max_duration | Number | Maximum number of minute of the video searched | 10, 20, 30 | - |
105
+ | search | String | Type of search targeted | video, pornstars, gifs | video |
106
+ | promo | String | Category of video | premium, modelhub | - |
107
+
108
+ </details>
109
+
110
+
111
+ <details>
112
+ <summary><b>Lists of keys available for a search by video</b> (click to show)</summary>
113
+
114
+ | name of keys | return type | description |
115
+ | :---------------- | :---------- | :----------------------------- |
116
+ | related_search | String | List of the related researches |
117
+ | related_pornstars | String | List of the related pornstars |
118
+
119
+ </details>
120
+
121
+ <details>
122
+ <summary><b>Lists of keys available for a porn actor search</b> (click to show)</summary>
123
+
124
+ | name of keys | return type | description |
125
+ | :--- | :---------- | :--- |
126
+ | actor | String | Name of the actor |
127
+ | video_number | Number | Number of video of the actor |
128
+ | view_number | Number | Number of view of the actor |
129
+ | rank | Number | Rank of the actor |
130
+
131
+ </details>
132
+
133
+ <details>
134
+ <summary><b>Lists of keys available for a gifs search</b> (click to show)</summary>
135
+
136
+ | name of keys | return type | description |
137
+ | :--- | :---------- | :--- |
138
+ | title | String | Title of the gif |
139
+ | thumbnail_url | String | Url of the thumbnail |
140
+ | link_mp4 | String | Url of the mp4 version |
141
+ | link_webm | String | Url of the webm version |
142
+
143
+ </details>
144
+
145
+ ### Scraping of a special search page by category
146
+
147
+ There are two kind of possible way to search on pornhub. The first one is to search by term and the second one is to search by filter. This call is for the search by category and subcategory.
148
+
149
+ ```js
150
+ async video(keys, options)
151
+ ```
152
+
153
+ | name | type | description | default |
154
+ | :------ | :----------------------------------------------- | :--------------------------------------- | :-------- |
155
+ | keys | Array or String if there is only one option | [OPTIONNAL] List of the keys | null |
156
+ | options | Array | [OPTIONNAL] List of the optional options | null |
157
+
158
+ <details>
159
+ <summary><b>Lists of keys available for a special search page by category</b> (click to show)</summary>
160
+
161
+ | name of keys | return type | description |
162
+ | :---------------- | :---------- | :----------------------------- |
163
+ | related_search | String | List of the related videos |
164
+ | related_pornstars | String | List of the related pornstars |
165
+ </details>
166
+
167
+ <details>
168
+ <summary><b>Lists of options available for a search</b> (click to show)</summary>
169
+
170
+ | name of options | return type | description | options | default |
171
+ | :-------------- | :---------- | :--------------------------------------------- | :------------------------------ | :-------- |
172
+ | page | Number | Number of page to scraper | - | 1 |
173
+ | production | String | Type of production targeted | homemade, professional | - |
174
+ | min_duration | Number | Minimum number of minute of the video searched | 10, 20, 30 | - |
175
+ | max_duration | Number | Maximum number of minute of the video searched | 10, 20, 30 | - |
176
+ | search | String | Type of search targeted | video, pornstars, gifs | video |
177
+ | promo | String | Category of video | premium, modelhub | - |
178
+ | filter | String | Filter of the page | MOST_VIEWED, HOTTEST, TOP_RATED | - |
179
+
180
+ </details>
181
+
182
+ ### Model page pornhub
183
+
184
+ ```js
185
+ async model(name, keys)
186
+ ```
187
+
188
+ | name | type | description |
189
+ | :--- | :---------- | :--- |
190
+ | name | String | name of the model in pornhub |
191
+ | keys | Array or String if there is only one option | List of the keys |
192
+ | type | String | There is two kind of model : pornstar or model |
193
+
194
+ <details>
195
+ <summary><b>Lists of keys available for a model page</b> (click to show)</summary>
196
+
197
+ | name of keys | return type | description |
198
+ | :--- | :---------- | :--- |
199
+ | title | String | The name of the model |
200
+ | description | String | The description of the model |
201
+ | rank_model | String | The actual rank of the model |
202
+ | rank_week_model | String | The rank of the model for the week |
203
+ | rank_month_model | String | The rank of the model for this month |
204
+ | rank_last_month_model | String | The rank of the model for last month |
205
+ | rank_year_model | String | The rank of the model for this year |
206
+ | relationship_status | String | The status of the model (Work only if the model has filled up this field) |
207
+ | interested_in | String | The interest of the model (Work only if the model has filled up this field) |
208
+ | gender | String | The gender of the model (Work only if the model has filled up this field) |
209
+ | birthday | Date | The birthday of the model (Work only if the model has filled up this field) |
210
+ | age | Number | The age of the model (Work only if the model has filled up this field) |
211
+ | height | String | The height of the model (Work only if the model has filled up this field) |
212
+ | weight | String | The weight of the model (Work only if the model has filled up this field) |
213
+ | ethnicity | String | The ethnicity of the model (Work only if the model has filled up this field) |
214
+ | video_views | Number | The number of video view of the model (Work only if the model has filled up this field) |
215
+ | profile_views | Number | The number of profil view of the model (Work only if the model has filled up this field) |
216
+ | videos_watched | Number | The number of video watched by the model (Work only if the model has filled up this field) |
217
+ | joined | String | The period passed after the model joined Pornhub |
218
+
219
+ </details>
220
+
221
+ ### Examples
222
+
223
+ <details>
224
+ <summary><b>Scraping the title of a video</b> (click to show)</summary>
225
+
226
+ ```js
227
+ const pornhub = require('@justalk/pornhub-api');
228
+ const video = await pornhub.page(url, ['title']);
229
+ ```
230
+
231
+
232
+ ```json
233
+ {
234
+ "title": "Name of the video"
235
+ }
236
+ ```
237
+
238
+ </details>
239
+
240
+ <details>
241
+ <summary><b>Scraping the title of a video and the description</b> (click to show)</summary>
242
+
243
+ ```js
244
+ const pornhub = require('@justalk/pornhub-api');
245
+ const video = await pornhub.page(url, ['title','description']);
246
+ ```
247
+
248
+ ```json
249
+ {
250
+ "title": "Name of the video",
251
+ "description": "Description of the video"
252
+ }
253
+ ```
254
+
255
+ </details>
256
+
257
+ <details>
258
+ <summary><b>Scraping the name of the pornstars and the downloads links</b> (click to show)</summary>
259
+
260
+ ```js
261
+ const pornhub = require('@justalk/pornhub-api');
262
+ const video = await pornhub.page(url, ['title','pornstars','download_urls']);
263
+ ```
264
+
265
+ ```json
266
+ {
267
+ "title": "Title of the video",
268
+ "pornstars": ["Sophie A","Rocco B"],
269
+ "download_urls": {
270
+ "720" : "https://p.com/link1",
271
+ "480" : "https://p.com/link2",
272
+ "360" : "https://p.com/link3"
273
+ }
274
+ }
275
+ ```
276
+
277
+ </details>
278
+
279
+ <details>
280
+ <summary><b>Scraping a search pornhub without options</b> (click to show)</summary>
281
+
282
+ ```js
283
+ const pornhub = require('@justalk/pornhub-api');
284
+ const video = await pornhub.search("Aa",["title","link","premium","hd"]);
285
+ ```
286
+
287
+ ```json
288
+ [{
289
+ "link": "https://p.com/link1",
290
+ "title": "Title of the video",
291
+ "hd": true,
292
+ "premium": true
293
+ },{
294
+ "link": "https://p.com/link2",
295
+ "title": "Title of the video",
296
+ "hd": false,
297
+ "premium": false
298
+ }]
299
+ ```
300
+
301
+ </details>
302
+
303
+ <details>
304
+ <summary><b>Scraping a search pornhub with options</b> (click to show)</summary>
305
+
306
+ ```js
307
+ const pornhub = require('@justalk/pornhub-api');
308
+ const video = await pornhub.search("Aa",["actor","rank"],{production: 'homemade', search: 'pornstars'});
309
+ ```
310
+
311
+ ```json
312
+ [{
313
+ "actor": "Herica Alue",
314
+ "rank": 8005,
315
+ },{
316
+ "actor": "Robert Laach",
317
+ "rank": 60
318
+ },{
319
+ "actor": "Aalix Lolo",
320
+ "rank": 6500
321
+ }]
322
+ ```
323
+
324
+ </details>
325
+
326
+ ### How to test/contribute
327
+
328
+ <details>
329
+ <summary><b>How to test the API ?</b> (click to show)</summary>
330
+
331
+ For testing, install the node project and run the test command.
332
+
333
+ ```shell
334
+ node install
335
+ npm test
336
+ ```
337
+
338
+ Also, you can use the command under for running the test without the linter
339
+
340
+ ```shell
341
+ npm run test-no
342
+ ```
343
+
344
+ The tests are not execute on pornhub directly, the calls to pornhub are all mock with `nock` to save html page of pornhub.
345
+ It has been done for having page that wont evolve through time. By example, if a comment is added on the real link, the tests will still be ok.
346
+
347
+ </details>
348
+
349
+ <details>
350
+ <summary><b>How to contribute ?</b> (click to show)</summary>
351
+
352
+ Any contribution is welcomed !
353
+
354
+ If you find an issue or just want to add your stone to the castle :
355
+
356
+ 1. Open an issue
357
+ 2. Fork the repository
358
+ 3. Create a new branch
359
+ 4. Pull Request your change
360
+ 5. Wait until I check your code
361
+ 6. Merge and add your name on this page forever !
362
+
363
+ </details>
364
+
365
+ ### Note
366
+
367
+ <details>
368
+ <summary><b>Why does it not work in my country ?</b> (click to show)</summary>
369
+ If pornhub is blocked in your country, the API will obviously not work. You will need a proxy.
370
+ </details>
371
+ <details>
372
+ <summary><b>Why does it not work at all sometimes ?</b> (click to show)</summary>
373
+ Pornuhub has a scraper protection, if you scrap the website violently (let say hundreds pages in 10 seconds), your ip will be flag as a bot for few minute. Please be gentle with pornhub's server !
374
+ </details>
375
+
376
+ ## License
377
+
378
+ MIT - Copyright &copy; [JUSTAL Kevin](https://teamkd.online/)