Guest User

parse dataset9

a guest
Jan 31st, 2026
974
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 6.99 KB | None | 0 0
  1. #!/usr/bin/env python3
  2. """
  3. Scrape Dataset 9 file list from DOJ website and download PDFs one by one.
  4. Uses Playwright to handle age verification and pagination.
  5. """
  6.  
  7. import asyncio
  8. import os
  9. import json
  10. from pathlib import Path
  11. from playwright.async_api import async_playwright
  12.  
  13. BASE_URL = "https://www.justice.gov/epstein/doj-disclosures/data-set-9-files"
  14. OUTPUT_DIR = Path("~/epstein-doj-2026-01-30/DataSet_9_individual")
  15. INDEX_FILE = Path("~/epstein-doj-2026-01-30/dataset9_index.json")
  16.  
  17. async def scrape_all_pages(start_page=0):
  18.     """Scrape all pages to build index of PDF files."""
  19.     all_files = []
  20.  
  21.     # Load existing index if resuming
  22.     if start_page > 0 and INDEX_FILE.exists():
  23.         with open(INDEX_FILE, 'r') as f:
  24.             all_files = json.load(f)
  25.         print(f"Resuming from page {start_page}, loaded {len(all_files)} existing files")
  26.  
  27.     async with async_playwright() as p:
  28.         browser = await p.chromium.launch(headless=False)  # Set to True for headless
  29.         context = await browser.new_context()
  30.  
  31.         # Set the age verification cookie
  32.         await context.add_cookies([{
  33.             'name': 'justiceGovAgeVerified',
  34.             'value': 'true',
  35.             'domain': 'www.justice.gov',
  36.             'path': '/'
  37.         }])
  38.  
  39.         page = await context.new_page()
  40.  
  41.         # First, find the last page number
  42.         print("Finding total pages...")
  43.         await page.goto(f"{BASE_URL}?page=0")
  44.         await page.wait_for_load_state('networkidle')
  45.  
  46.         # Find the "Last" link to get max page
  47.         last_link = await page.query_selector('a[aria-label="Last page"]')
  48.         if last_link:
  49.             href = await last_link.get_attribute('href')
  50.             max_page = int(href.split('page=')[1])
  51.             print(f"Found {max_page + 1} pages (0 to {max_page})")
  52.         else:
  53.             print("Could not find last page link, using manual max...")
  54.             max_page = 20500  # Dataset 9 has ~20,450 pages
  55.  
  56.         # Scrape each page
  57.         current_page = start_page
  58.         while current_page <= max_page:
  59.             print(f"Scraping page {current_page}/{max_page}...")
  60.             await page.goto(f"{BASE_URL}?page={current_page}")
  61.             await page.wait_for_load_state('networkidle')
  62.  
  63.             # Extract PDF links
  64.             links = await page.query_selector_all('a[href*="/epstein/files/DataSet%209/"]')
  65.  
  66.             if not links:
  67.                 print(f"No files found on page {current_page}, stopping.")
  68.                 break
  69.  
  70.             for link in links:
  71.                 href = await link.get_attribute('href')
  72.                 filename = href.split('/')[-1]
  73.                 if filename not in [f['filename'] for f in all_files]:
  74.                     all_files.append({
  75.                         'filename': filename,
  76.                         'url': f"https://www.justice.gov{href}",
  77.                         'downloaded': False
  78.                     })
  79.  
  80.             print(f"  Found {len(links)} links, total unique files: {len(all_files)}")
  81.             current_page += 1
  82.  
  83.             # Save progress every 100 pages
  84.             if current_page % 100 == 0:
  85.                 with open(INDEX_FILE, 'w') as f:
  86.                     json.dump(all_files, f, indent=2)
  87.                 print(f"  Progress saved at page {current_page}")
  88.  
  89.             # Small delay to be polite
  90.             await asyncio.sleep(0.5)
  91.  
  92.         await browser.close()
  93.  
  94.     # Save index
  95.     with open(INDEX_FILE, 'w') as f:
  96.         json.dump(all_files, f, indent=2)
  97.  
  98.     print(f"\nSaved index with {len(all_files)} files to {INDEX_FILE}")
  99.     return all_files
  100.  
  101.  
  102. async def download_files(start_from=0):
  103.     """Download PDFs from the index."""
  104.  
  105.     if not INDEX_FILE.exists():
  106.         print("Index file not found. Run scrape first.")
  107.         return
  108.  
  109.     with open(INDEX_FILE, 'r') as f:
  110.         all_files = json.load(f)
  111.  
  112.     OUTPUT_DIR.mkdir(parents=True, exist_ok=True)
  113.  
  114.     async with async_playwright() as p:
  115.         browser = await p.chromium.launch(headless=False)
  116.         context = await browser.new_context(accept_downloads=True)
  117.  
  118.         # Set the age verification cookie
  119.         await context.add_cookies([{
  120.             'name': 'justiceGovAgeVerified',
  121.             'value': 'true',
  122.             'domain': 'www.justice.gov',
  123.             'path': '/'
  124.         }])
  125.  
  126.         page = await context.new_page()
  127.  
  128.         downloaded = 0
  129.         skipped = 0
  130.         failed = 0
  131.  
  132.         for i, file_info in enumerate(all_files[start_from:], start=start_from):
  133.             filename = file_info['filename']
  134.             url = file_info['url']
  135.             output_path = OUTPUT_DIR / filename
  136.  
  137.             if output_path.exists():
  138.                 skipped += 1
  139.                 continue
  140.  
  141.             print(f"[{i+1}/{len(all_files)}] Downloading {filename}...")
  142.  
  143.             try:
  144.                 # Navigate to the file URL - this will trigger a download
  145.                 async with page.expect_download(timeout=60000) as download_info:
  146.                     await page.goto(url)
  147.  
  148.                 download = await download_info.value
  149.                 await download.save_as(output_path)
  150.  
  151.                 file_info['downloaded'] = True
  152.                 downloaded += 1
  153.  
  154.                 # Save progress periodically
  155.                 if downloaded % 10 == 0:
  156.                     with open(INDEX_FILE, 'w') as f:
  157.                         json.dump(all_files, f, indent=2)
  158.                     print(f"  Progress saved. Downloaded: {downloaded}, Skipped: {skipped}")
  159.  
  160.                 await asyncio.sleep(0.3)  # Small delay between downloads
  161.  
  162.             except Exception as e:
  163.                 print(f"  FAILED: {e}")
  164.                 failed += 1
  165.  
  166.                 # If we hit too many failures in a row, pause
  167.                 if failed > 5:
  168.                     print("Too many failures, pausing for 30 seconds...")
  169.                     await asyncio.sleep(30)
  170.                     failed = 0
  171.  
  172.         await browser.close()
  173.  
  174.     # Final save
  175.     with open(INDEX_FILE, 'w') as f:
  176.         json.dump(all_files, f, indent=2)
  177.  
  178.     print(f"\nDone! Downloaded: {downloaded}, Skipped: {skipped}, Failed: {failed}")
  179.  
  180.  
  181. async def main():
  182.     import sys
  183.  
  184.     if len(sys.argv) < 2:
  185.         print("Usage:")
  186.         print("  python scrape_dataset9.py scrape         - Build index of all files")
  187.         print("  python scrape_dataset9.py scrape 500     - Resume scraping from page 500")
  188.         print("  python scrape_dataset9.py download       - Download all files from index")
  189.         print("  python scrape_dataset9.py download 100   - Resume download from file #100")
  190.         return
  191.  
  192.     cmd = sys.argv[1]
  193.  
  194.     if cmd == 'scrape':
  195.         start_page = int(sys.argv[2]) if len(sys.argv) > 2 else 0
  196.         await scrape_all_pages(start_page)
  197.     elif cmd == 'download':
  198.         start = int(sys.argv[2]) if len(sys.argv) > 2 else 0
  199.         await download_files(start)
  200.     else:
  201.         print(f"Unknown command: {cmd}")
  202.  
  203.  
  204. if __name__ == '__main__':
  205.     asyncio.run(main())
  206.  
Advertisement
Add Comment
Please, Sign In to add comment