Skip to content

Commit efdc209

Browse files
Add comprehensive data schema and scraping guide documentation
Co-authored-by: devinschumacher <45643901+devinschumacher@users.noreply.github.com>
1 parent f8a1933 commit efdc209

1 file changed

Lines changed: 313 additions & 0 deletions

File tree

Lines changed: 313 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,313 @@
1+
# File Type Scraper - Data Schema and Sources Guide
2+
3+
## File Types Page Schema
4+
5+
The scraper outputs data in the `FileTypeRawData` schema (defined in `apps/files/types/index.d.ts`), which is the format stored in JSON files at `public/data/files/individual/{extension}.json`.
6+
7+
### Complete Schema Structure
8+
9+
```typescript
10+
interface FileTypeRawData {
11+
// Core identification
12+
slug: string; // URL-friendly identifier (e.g., "pdf")
13+
extension: string; // File extension (e.g., "pdf")
14+
name: string; // Full name (e.g., "Portable Document Format File")
15+
16+
// Categorization
17+
category?: string; // Category name (e.g., "Page Layout Files")
18+
category_slug?: string; // URL-friendly category (e.g., "page-layout-files")
19+
20+
// Description
21+
summary?: string; // Brief description/summary
22+
23+
// Developer/Creator
24+
developer?: string; // Developer name
25+
developer_org?: string; // Organization name
26+
developer_name?: string; // Developer full name
27+
developer_slug?: string; // URL-friendly developer name
28+
29+
// Popularity metrics
30+
rating?: number; // Rating (1-5 scale)
31+
votes?: number; // Number of votes
32+
popularity?: {
33+
rating: number;
34+
votes: number;
35+
};
36+
37+
// Detailed information
38+
more_information?: {
39+
content?: string[]; // Additional info paragraphs
40+
description?: string[]; // Detailed descriptions
41+
screenshot?: {
42+
url: string;
43+
alt: string;
44+
caption: string;
45+
};
46+
};
47+
48+
// Technical specifications
49+
technical_info?: {
50+
content?: string[]; // Technical details
51+
};
52+
53+
// Usage instructions
54+
how_to_open?: {
55+
instructions?: string[]; // Opening instructions
56+
programs?: Array<{
57+
name: string;
58+
url?: string;
59+
}>;
60+
};
61+
62+
how_to_convert?: {
63+
instructions?: string[]; // Conversion instructions
64+
};
65+
66+
// Software support
67+
programs?: {
68+
[platform: string]: Array<{ // e.g., "Windows", "macOS", "Linux"
69+
name: string;
70+
url?: string;
71+
license?: string;
72+
}>;
73+
};
74+
75+
// Media
76+
images?: Array<{
77+
url: string;
78+
alt: string;
79+
caption: string;
80+
}>;
81+
82+
// Metadata
83+
common_filenames?: string[]; // Common filename examples
84+
updated_at?: string; // Last update timestamp
85+
last_updated?: string; // Human-readable update date
86+
87+
// Source tracking
88+
sources?: Array<{
89+
url: string; // Source URL
90+
retrieved_at: string; // ISO timestamp
91+
}>;
92+
}
93+
```
94+
95+
## Data Sources - What We Extract
96+
97+
### 1. fileinfo.com (Primary Source)
98+
99+
**URL Pattern**: `https://fileinfo.com/extension/{extension}`
100+
101+
**Data Extracted**:
102+
-**Name**: Full file type name from `<h1>` tag
103+
-**Summary**: Description from `.infoBox p`
104+
-**Category**: From category links
105+
-**Developer**: From developer section
106+
-**Rating**: Numerical rating (1-5)
107+
-**Votes**: Number of user votes
108+
-**More Information**: Content paragraphs from `.moreInfo`
109+
-**How to Open**: Instructions and program lists
110+
-**Programs**: Compatible software with URLs
111+
112+
**HTML Selectors Used**:
113+
```javascript
114+
$('h1').first() // Name
115+
$('.infoBox p').first() // Summary
116+
$('a[href*="/filetypes/"]').first() // Category
117+
$('td:contains("Developer:")').next('td') // Developer
118+
$('.rating').first() // Rating
119+
$('.moreInfo p') // Info sections
120+
$('ul li a, .programs a') // Programs
121+
```
122+
123+
### 2. files.org (Alternative Source)
124+
125+
**URL Pattern**: `https://file.org/extension/{extension}`
126+
127+
**Data Extracted**:
128+
-**Name**: File type name from `<h1>`
129+
-**Summary**: From `.extension-description` or meta description
130+
-**Category**: From `.category` span
131+
-**Developer**: From "Developer:" text pattern
132+
-**More Information**: Content from multiple sections
133+
-**Technical Info**: Technical specifications
134+
-**How to Open**: Opening instructions
135+
-**Programs**: Software list with URLs
136+
-**MIME Type**: MIME type information
137+
138+
**HTML Selectors Used**:
139+
```javascript
140+
$('h1').first() // Name
141+
$('.extension-description p').first() // Summary
142+
$('.category').first() // Category
143+
$('h2, h3').each() + next elements // Sections
144+
$('li a').each() // Programs
145+
```
146+
147+
### 3. fileformat.com (API + Web Fallback)
148+
149+
**Primary**: API endpoints (tried in order):
150+
- `https://www.fileformat.com/api/v1/file-extension/{extension}`
151+
- `https://fileformat.com/api/extension/{extension}`
152+
- `https://api.fileformat.com/v1/format/{extension}`
153+
154+
**Fallback**: Web scraping from `https://docs.fileformat.com/extension/{extension}/`
155+
156+
**Data Extracted**:
157+
-**Name**: File type name
158+
-**Summary**: Description from meta tag
159+
-**Category**: Category classification
160+
-**Developer**: Creator/company info
161+
-**MIME Type**: MIME type from API or text
162+
-**Technical Info**: Specifications
163+
-**Programs**: Software by platform (from API)
164+
-**Content**: Main content paragraphs
165+
166+
**API Response Fields Mapped**:
167+
```javascript
168+
json.name / json.title / json.fullName → name
169+
json.description / json.summary → summary
170+
json.category → category
171+
json.developer / json.creator / json.company → developer
172+
json.mimeType / json.mime_type → mime_type
173+
json.programs / json.applicationsprograms (by platform)
174+
```
175+
176+
## Data Merging Strategy
177+
178+
When data comes from multiple sources, the merger (`data-merger.ts`) combines them intelligently:
179+
180+
### Priority Rules:
181+
1. **Name**: Longest, most descriptive name wins
182+
2. **Summary**: Longest, most informative summary selected
183+
3. **Developer**: Most specific information preferred
184+
4. **Content**: All unique paragraphs merged and deduplicated
185+
5. **Programs**: Combined by platform, deduplicated by name
186+
6. **Ratings**: Averaged across all sources
187+
7. **Sources**: All source URLs and timestamps tracked
188+
189+
### Example Merge:
190+
```javascript
191+
// fileinfo.com provides:
192+
{
193+
name: "PDF File",
194+
rating: 4.2,
195+
votes: 5000,
196+
content: ["Info A", "Info B"]
197+
}
198+
199+
// files.org provides:
200+
{
201+
name: "Portable Document Format File", // ← Longer, used
202+
rating: 4.0,
203+
votes: 3000,
204+
content: ["Info B", "Info C"]
205+
}
206+
207+
// Merged result:
208+
{
209+
name: "Portable Document Format File", // Best from files.org
210+
rating: 4.1, // Average: (4.2 + 4.0) / 2
211+
votes: 4000, // Average: (5000 + 3000) / 2
212+
content: ["Info A", "Info B", "Info C"], // Deduplicated union
213+
sources: [
214+
{ url: "https://fileinfo.com/...", ... },
215+
{ url: "https://file.org/...", ... }
216+
]
217+
}
218+
```
219+
220+
## How to Run Scrapes
221+
222+
### 1. Scrape Specific Extensions
223+
```bash
224+
npm run scrape -- -e pdf,docx,xlsx
225+
```
226+
227+
### 2. Scrape A-Z Everything (All 10,477+ Extensions)
228+
229+
**Option A: Update All Existing Files**
230+
```bash
231+
npm run scrape -- -u
232+
```
233+
This reads all extensions from `public/data/files/individual/` and re-scrapes them.
234+
235+
**Option B: Scrape from Index**
236+
```bash
237+
npm run scrape
238+
```
239+
Without `-e` flag, it loads all extensions from the existing index.
240+
241+
**Option C: Scrape All with Custom Batch Size**
242+
```bash
243+
npm run scrape -- -u -b 5
244+
```
245+
Process 5 at a time (safer for rate limiting).
246+
247+
### 3. Scrape Only New (Missing) Extensions
248+
```bash
249+
npm run scrape
250+
```
251+
Without `-u` flag, skips existing files.
252+
253+
### 4. Scrape from Specific Sources Only
254+
```bash
255+
npm run scrape -- -e pdf -s fileinfo,files.org
256+
```
257+
Excludes fileformat.com from the scrape.
258+
259+
### 5. Generate Indexes After Scraping
260+
```bash
261+
npm run generate-indexes
262+
```
263+
Creates:
264+
- `index.json` (all extensions alphabetically)
265+
- `alphabet-index.json` (grouped by first letter)
266+
- `categories/*.json` (grouped by category)
267+
- `popular.json` (top 100 by votes)
268+
- `search-index.json` (search-optimized)
269+
270+
## Complete A-Z Scraping Workflow
271+
272+
```bash
273+
# Step 1: Test with a few extensions first
274+
npm run test-scraper test-batch pdf,txt,jpg,mp3
275+
276+
# Step 2: Scrape all extensions (this will take hours!)
277+
# Recommended: Use small batch size for safety
278+
npm run scrape -- -u -b 5
279+
280+
# Step 3: Regenerate all indexes
281+
npm run generate-indexes
282+
283+
# Step 4: Validate the data
284+
npm run test-scraper validate ./public/data/files/individual
285+
```
286+
287+
## Performance Estimates
288+
289+
With current rate limiting (2 seconds between requests):
290+
- **1 extension**: ~6-10 seconds (3 sources × 2-3s each)
291+
- **100 extensions**: ~10-17 minutes
292+
- **1,000 extensions**: ~1.7-2.8 hours
293+
- **10,477 extensions**: ~17-29 hours (full A-Z)
294+
295+
Batch size affects memory but not total time (rate limiting is the bottleneck).
296+
297+
## Tips for A-Z Scraping
298+
299+
1. **Start Small**: Test with `-e a,b,c` first
300+
2. **Use Small Batches**: `-b 5` or `-b 10` max
301+
3. **Monitor Progress**: Watch the console output
302+
4. **Resume Capability**: If interrupted, re-run without `-u` to skip completed
303+
5. **Validate After**: Run `npm run test-scraper validate` to check quality
304+
6. **Generate Indexes**: Always run `npm run generate-indexes` after scraping
305+
306+
## Schema Compatibility
307+
308+
The scraper output (`MergedFileData`) is compatible with the existing `FileTypeRawData` schema used throughout the application. The transformer (`files-transformer.ts`) converts it to `FileTypeTemplateData` for page display.
309+
310+
**Data Flow**:
311+
```
312+
Scrapers → MergedFileData → JSON Files (FileTypeRawData) → Transformer → FileTypeTemplateData → UI
313+
```

0 commit comments

Comments
 (0)