@anysiteio/agent-skills 1.4.0 → 2.0.1
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.
- package/.claude-plugin/marketplace.json +49 -1
- package/.claude-plugin/plugin.json +5 -1
- package/README.md +27 -33
- package/bin/install.js +196 -135
- package/bundles.json +19 -0
- package/package.json +3 -2
- package/skills/anysite-audience-analysis/SKILL.md +110 -38
- package/skills/anysite-audience-analysis/references/PLATFORM_COVERAGE.md +38 -19
- package/skills/anysite-audience-analysis/references/TOOL_MAPPING.md +16 -11
- package/skills/anysite-brand-reputation/SKILL.md +105 -43
- package/skills/anysite-competitor-analyzer/SKILL.md +170 -111
- package/skills/anysite-competitor-intelligence/SKILL.md +201 -116
- package/skills/anysite-competitor-intelligence/references/ANALYSIS_PATTERNS.md +17 -13
- package/skills/anysite-content-analytics/SKILL.md +101 -33
- package/skills/anysite-crm-account-brief/SKILL.md +71 -0
- package/skills/anysite-crm-audit/SKILL.md +59 -0
- package/skills/anysite-crm-champions/SKILL.md +76 -0
- package/skills/anysite-crm-competitor-intel/SKILL.md +74 -0
- package/skills/anysite-crm-enrich/SKILL.md +84 -0
- package/skills/anysite-crm-lookalikes/SKILL.md +64 -0
- package/skills/anysite-crm-prospect/SKILL.md +90 -0
- package/skills/anysite-crm-score/SKILL.md +72 -0
- package/skills/anysite-crm-setup/SKILL.md +147 -0
- package/skills/anysite-crm-signals/SKILL.md +96 -0
- package/skills/anysite-influencer-discovery/SKILL.md +123 -71
- package/skills/anysite-lead-generation/SKILL.md +288 -256
- package/skills/anysite-lead-generation/references/LINKEDIN_STRATEGIES.md +79 -71
- package/skills/anysite-lead-generation/references/WEB_SCRAPING.md +121 -87
- package/skills/anysite-market-research/SKILL.md +117 -68
- package/skills/anysite-mcp/SKILL.md +128 -0
- package/skills/anysite-mcp-migration/SKILL.md +19 -8
- package/skills/anysite-person-analyzer/SKILL.md +86 -53
- package/skills/anysite-trend-analysis/SKILL.md +119 -55
- package/skills/anysite-vc-analyst/SKILL.md +12 -2
- package/skills/competitor-discovery/SKILL.md +350 -0
- package/skills/customer-pain-mining/SKILL.md +318 -0
- package/skills/positioning-map/SKILL.md +314 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Web Scraping for Contact Extraction
|
|
2
2
|
|
|
3
|
-
Strategies and techniques for extracting contact information from company websites using anysite MCP.
|
|
3
|
+
Strategies and techniques for extracting contact information from company websites using anysite MCP v2.
|
|
4
4
|
|
|
5
5
|
## Overview
|
|
6
6
|
|
|
@@ -13,18 +13,20 @@ Web scraping complements LinkedIn lead generation by:
|
|
|
13
13
|
|
|
14
14
|
## Contact Extraction Tools
|
|
15
15
|
|
|
16
|
-
###
|
|
16
|
+
### Web Page Parsing (v2)
|
|
17
17
|
|
|
18
18
|
Primary tool for extracting contacts from web pages.
|
|
19
19
|
|
|
20
|
+
**v2 Call**: `execute("webparser", "parse", "parse", {"url": ..., "extract_contacts": true})`
|
|
21
|
+
|
|
20
22
|
**Basic Usage**:
|
|
21
23
|
```
|
|
22
|
-
Tool:
|
|
24
|
+
Tool: mcp__anysite__execute
|
|
23
25
|
Parameters:
|
|
24
|
-
-
|
|
25
|
-
-
|
|
26
|
-
-
|
|
27
|
-
- only_main_content: true
|
|
26
|
+
- source: "webparser"
|
|
27
|
+
- category: "parse"
|
|
28
|
+
- endpoint: "parse"
|
|
29
|
+
- params: {"url": "https://company.com/contact", "extract_contacts": true, "strip_all_tags": true, "only_main_content": true}
|
|
28
30
|
```
|
|
29
31
|
|
|
30
32
|
**Returns**:
|
|
@@ -32,22 +34,34 @@ Parameters:
|
|
|
32
34
|
- Phones: Phone numbers in various formats
|
|
33
35
|
- Social links: LinkedIn, Twitter, Facebook, Instagram
|
|
34
36
|
- Content: Page text for additional parsing
|
|
37
|
+
- `cache_key`: For use with query_cache and export_data
|
|
35
38
|
|
|
36
39
|
**Best Practices**:
|
|
37
40
|
- Set `extract_contacts: true` to enable contact extraction
|
|
38
41
|
- Use `only_main_content: true` to avoid footer/header noise
|
|
39
42
|
- Try multiple page variations (/contact, /about, /team)
|
|
40
43
|
|
|
41
|
-
###
|
|
44
|
+
### Sitemap Parsing (v2)
|
|
42
45
|
|
|
43
46
|
Discover all pages on a website to find contact information.
|
|
44
47
|
|
|
48
|
+
**v2 Call**: `discover("webparser", "parse")` to find the sitemap endpoint, then `execute(...)` with discovered endpoint and params.
|
|
49
|
+
|
|
45
50
|
**Basic Usage**:
|
|
46
51
|
```
|
|
47
|
-
|
|
52
|
+
Step 1: Discover sitemap endpoint
|
|
53
|
+
Tool: mcp__anysite__discover
|
|
54
|
+
Parameters:
|
|
55
|
+
- source: "webparser"
|
|
56
|
+
- category: "parse"
|
|
57
|
+
|
|
58
|
+
Step 2: Execute with discovered endpoint
|
|
59
|
+
Tool: mcp__anysite__execute
|
|
48
60
|
Parameters:
|
|
49
|
-
-
|
|
50
|
-
-
|
|
61
|
+
- source: "webparser"
|
|
62
|
+
- category: "parse"
|
|
63
|
+
- endpoint: <discovered_sitemap_endpoint>
|
|
64
|
+
- params: {"url": "https://company.com", "count": 100}
|
|
51
65
|
```
|
|
52
66
|
|
|
53
67
|
**Returns**:
|
|
@@ -58,7 +72,7 @@ Parameters:
|
|
|
58
72
|
**Best Practices**:
|
|
59
73
|
- Start with count=100 to get comprehensive coverage
|
|
60
74
|
- Filter results for relevant pages (contact, team, about, leadership)
|
|
61
|
-
- Parse identified pages with
|
|
75
|
+
- Parse identified pages with execute("webparser", "parse", "parse", ...)
|
|
62
76
|
|
|
63
77
|
## Common Page Patterns
|
|
64
78
|
|
|
@@ -84,7 +98,7 @@ Parameters:
|
|
|
84
98
|
|
|
85
99
|
**Example**:
|
|
86
100
|
```
|
|
87
|
-
|
|
101
|
+
execute("webparser", "parse", "parse", {"url": "https://company.com/contact", "extract_contacts": true})
|
|
88
102
|
|
|
89
103
|
Expected data:
|
|
90
104
|
- General company email (info@, contact@, hello@)
|
|
@@ -115,7 +129,7 @@ Expected data:
|
|
|
115
129
|
|
|
116
130
|
**Example**:
|
|
117
131
|
```
|
|
118
|
-
|
|
132
|
+
execute("webparser", "parse", "parse", {"url": "https://company.com/about", "extract_contacts": true})
|
|
119
133
|
|
|
120
134
|
Expected data:
|
|
121
135
|
- Leadership emails
|
|
@@ -147,7 +161,7 @@ Expected data:
|
|
|
147
161
|
|
|
148
162
|
**Example**:
|
|
149
163
|
```
|
|
150
|
-
|
|
164
|
+
execute("webparser", "parse", "parse", {"url": "https://company.com/team", "extract_contacts": true})
|
|
151
165
|
|
|
152
166
|
Expected data:
|
|
153
167
|
- Individual names and titles
|
|
@@ -177,7 +191,7 @@ Expected data:
|
|
|
177
191
|
|
|
178
192
|
**Example**:
|
|
179
193
|
```
|
|
180
|
-
|
|
194
|
+
execute("webparser", "parse", "parse", {"url": "https://company.com/locations", "extract_contacts": true})
|
|
181
195
|
|
|
182
196
|
Expected data:
|
|
183
197
|
- Office-specific emails
|
|
@@ -331,11 +345,14 @@ Extracted:
|
|
|
331
345
|
|
|
332
346
|
1. **Get sitemap**
|
|
333
347
|
```
|
|
334
|
-
|
|
348
|
+
discover("webparser", "parse") -> find sitemap endpoint -> execute(...)
|
|
335
349
|
```
|
|
336
350
|
|
|
337
351
|
2. **Filter for relevant pages**
|
|
338
352
|
```
|
|
353
|
+
Use query_cache on sitemap results:
|
|
354
|
+
query_cache(cache_key, conditions=[{"field": "url", "operator": "contains", "value": "contact"}])
|
|
355
|
+
|
|
339
356
|
Filter sitemap results for:
|
|
340
357
|
- URLs containing: contact, about, team, location, office
|
|
341
358
|
- Exclude: blog, news, privacy, terms
|
|
@@ -344,7 +361,7 @@ Filter sitemap results for:
|
|
|
344
361
|
3. **Parse each relevant page**
|
|
345
362
|
```
|
|
346
363
|
For each filtered URL:
|
|
347
|
-
|
|
364
|
+
execute("webparser", "parse", "parse", {"url": "<url>", "extract_contacts": true})
|
|
348
365
|
```
|
|
349
366
|
|
|
350
367
|
4. **Consolidate and deduplicate**
|
|
@@ -359,8 +376,13 @@ For each filtered URL:
|
|
|
359
376
|
5. **Enrich with LinkedIn**
|
|
360
377
|
```
|
|
361
378
|
For team member names found:
|
|
362
|
-
|
|
363
|
-
|
|
379
|
+
execute("linkedin", "search", "search_users", {"first_name": "<first>", "last_name": "<last>", "company_keywords": "<company>"})
|
|
380
|
+
execute("linkedin", "user", "get", {"user": "<username>"})
|
|
381
|
+
```
|
|
382
|
+
|
|
383
|
+
6. **Export results**
|
|
384
|
+
```
|
|
385
|
+
export_data(cache_key, "csv") -> Download URL for consolidated contacts
|
|
364
386
|
```
|
|
365
387
|
|
|
366
388
|
**Expected Output**:
|
|
@@ -379,18 +401,18 @@ For team member names found:
|
|
|
379
401
|
1. **Find team page**
|
|
380
402
|
```
|
|
381
403
|
Try common patterns:
|
|
382
|
-
-
|
|
383
|
-
-
|
|
384
|
-
-
|
|
404
|
+
- execute("webparser", "parse", "parse", {"url": "https://company.com/team"})
|
|
405
|
+
- execute("webparser", "parse", "parse", {"url": "https://company.com/about/team"})
|
|
406
|
+
- execute("webparser", "parse", "parse", {"url": "https://company.com/people"})
|
|
385
407
|
|
|
386
408
|
Or use sitemap:
|
|
387
|
-
-
|
|
409
|
+
- discover("webparser", "parse") -> find sitemap endpoint -> execute(...)
|
|
388
410
|
- Filter for "team" or "people"
|
|
389
411
|
```
|
|
390
412
|
|
|
391
413
|
2. **Extract team members**
|
|
392
414
|
```
|
|
393
|
-
|
|
415
|
+
execute("webparser", "parse", "parse", {"url": "<team_url>", "extract_contacts": true})
|
|
394
416
|
|
|
395
417
|
Look for patterns:
|
|
396
418
|
- Name + Title combinations
|
|
@@ -405,25 +427,25 @@ Some team pages link to individual profiles:
|
|
|
405
427
|
- /team/john-smith
|
|
406
428
|
- /people/jane-doe
|
|
407
429
|
|
|
408
|
-
|
|
409
|
-
|
|
430
|
+
execute("webparser", "parse", "parse", {"url": "<individual_url>", "extract_contacts": true})
|
|
431
|
+
-> Often has direct email, phone
|
|
410
432
|
```
|
|
411
433
|
|
|
412
434
|
4. **Match to LinkedIn**
|
|
413
435
|
```
|
|
414
436
|
For each team member name:
|
|
415
|
-
|
|
416
|
-
first_name
|
|
417
|
-
last_name
|
|
418
|
-
company_keywords
|
|
419
|
-
)
|
|
437
|
+
execute("linkedin", "search", "search_users", {
|
|
438
|
+
"first_name": "<first>",
|
|
439
|
+
"last_name": "<last>",
|
|
440
|
+
"company_keywords": "<company>"
|
|
441
|
+
})
|
|
420
442
|
```
|
|
421
443
|
|
|
422
444
|
5. **Construct email addresses**
|
|
423
445
|
```
|
|
424
446
|
If email pattern detected from some team members:
|
|
425
447
|
- Apply pattern to all team members
|
|
426
|
-
- Example: john.doe@company.com
|
|
448
|
+
- Example: john.doe@company.com -> jane.smith@company.com
|
|
427
449
|
```
|
|
428
450
|
|
|
429
451
|
**Expected Output**:
|
|
@@ -440,7 +462,7 @@ If email pattern detected from some team members:
|
|
|
440
462
|
|
|
441
463
|
1. **Find locations page**
|
|
442
464
|
```
|
|
443
|
-
|
|
465
|
+
execute("webparser", "parse", "parse", {"url": "https://company.com/locations", "extract_contacts": true})
|
|
444
466
|
```
|
|
445
467
|
|
|
446
468
|
2. **Extract location information**
|
|
@@ -459,17 +481,17 @@ Some companies have per-location pages:
|
|
|
459
481
|
- /locations/san-francisco
|
|
460
482
|
- /offices/new-york
|
|
461
483
|
|
|
462
|
-
|
|
484
|
+
execute("webparser", "parse", "parse", {"url": "<location_url>", "extract_contacts": true})
|
|
463
485
|
```
|
|
464
486
|
|
|
465
487
|
4. **Find office leaders**
|
|
466
488
|
```
|
|
467
489
|
For each location:
|
|
468
|
-
|
|
469
|
-
title
|
|
470
|
-
company_keywords
|
|
471
|
-
location
|
|
472
|
-
)
|
|
490
|
+
execute("linkedin", "search", "search_users", {
|
|
491
|
+
"title": "Office Manager OR General Manager",
|
|
492
|
+
"company_keywords": "<company>",
|
|
493
|
+
"location": "<office_city>"
|
|
494
|
+
})
|
|
473
495
|
```
|
|
474
496
|
|
|
475
497
|
5. **Build location contact sheet**
|
|
@@ -481,6 +503,8 @@ Spreadsheet with:
|
|
|
481
503
|
- Local email
|
|
482
504
|
- Office manager name + LinkedIn
|
|
483
505
|
- Office manager email
|
|
506
|
+
|
|
507
|
+
Export via: export_data(cache_key, "csv")
|
|
484
508
|
```
|
|
485
509
|
|
|
486
510
|
**Expected Output**:
|
|
@@ -591,7 +615,7 @@ YouTube: youtube.com/[company]
|
|
|
591
615
|
|
|
592
616
|
**Parsing Strategy**:
|
|
593
617
|
```
|
|
594
|
-
|
|
618
|
+
execute("webparser", "parse", "parse", {"url": "<url>", "extract_contacts": true}) returns social links
|
|
595
619
|
|
|
596
620
|
Use social profiles to:
|
|
597
621
|
1. Verify company information
|
|
@@ -607,8 +631,8 @@ Social links found:
|
|
|
607
631
|
- Twitter: twitter.com/techcorp
|
|
608
632
|
|
|
609
633
|
Next steps:
|
|
610
|
-
|
|
611
|
-
|
|
634
|
+
execute("linkedin", "company", "get", {"company": "techcorp"}) -> Company details
|
|
635
|
+
execute("twitter", "user", "get", {"username": "techcorp"}) -> Twitter profile
|
|
612
636
|
```
|
|
613
637
|
|
|
614
638
|
## Error Handling & Troubleshooting
|
|
@@ -617,7 +641,7 @@ get_twitter_user("techcorp") → Twitter profile
|
|
|
617
641
|
|
|
618
642
|
#### 1. No Contacts Found
|
|
619
643
|
|
|
620
|
-
**Symptoms**:
|
|
644
|
+
**Symptoms**: execute() returns no emails or phones
|
|
621
645
|
|
|
622
646
|
**Causes**:
|
|
623
647
|
- JavaScript-rendered content (page loads dynamically)
|
|
@@ -639,6 +663,8 @@ get_twitter_user("techcorp") → Twitter profile
|
|
|
639
663
|
- Annual report might list executives
|
|
640
664
|
|
|
641
665
|
4. Use LinkedIn as primary source instead
|
|
666
|
+
|
|
667
|
+
5. Check llm_hint in response for guidance
|
|
642
668
|
```
|
|
643
669
|
|
|
644
670
|
#### 2. Malformed Contact Data
|
|
@@ -682,22 +708,23 @@ Extension: "123"
|
|
|
682
708
|
**Solutions**:
|
|
683
709
|
```
|
|
684
710
|
Filtering strategy:
|
|
685
|
-
1. only_main_content: true (remove footer/header)
|
|
711
|
+
1. Use only_main_content: true in params (remove footer/header)
|
|
686
712
|
2. Verify email domain matches company domain
|
|
687
713
|
3. Exclude common spam patterns (noreply@, donotreply@)
|
|
688
714
|
4. Filter out tracking/marketing emails
|
|
715
|
+
5. Use query_cache() to filter results after fetching
|
|
689
716
|
```
|
|
690
717
|
|
|
691
718
|
**Example Filter**:
|
|
692
719
|
```
|
|
693
720
|
Keep:
|
|
694
|
-
- john@company.com
|
|
695
|
-
- sales@company.com
|
|
721
|
+
- john@company.com
|
|
722
|
+
- sales@company.com
|
|
696
723
|
|
|
697
724
|
Discard:
|
|
698
|
-
- noreply@company.com
|
|
699
|
-
- partner@otherdomain.com
|
|
700
|
-
- ads@advertising-network.com
|
|
725
|
+
- noreply@company.com
|
|
726
|
+
- partner@otherdomain.com
|
|
727
|
+
- ads@advertising-network.com
|
|
701
728
|
```
|
|
702
729
|
|
|
703
730
|
#### 4. Rate Limiting or Blocking
|
|
@@ -711,16 +738,16 @@ Discard:
|
|
|
711
738
|
|
|
712
739
|
**Solutions**:
|
|
713
740
|
```
|
|
714
|
-
1.
|
|
715
|
-
2.
|
|
716
|
-
3.
|
|
717
|
-
4.
|
|
718
|
-
5.
|
|
741
|
+
1. Add delays between requests (30-60 seconds)
|
|
742
|
+
2. Rotate user agents (handled by MCP server)
|
|
743
|
+
3. Scrape during off-peak hours
|
|
744
|
+
4. Use smaller batch sizes
|
|
745
|
+
5. Check llm_hint in error response for specific guidance
|
|
719
746
|
```
|
|
720
747
|
|
|
721
748
|
**Best Practices**:
|
|
722
749
|
```
|
|
723
|
-
- Wait 30-60 seconds between
|
|
750
|
+
- Wait 30-60 seconds between execute() calls for the same domain
|
|
724
751
|
- Process 5-10 websites per batch
|
|
725
752
|
- Don't scrape same site multiple times rapidly
|
|
726
753
|
- Respect robots.txt
|
|
@@ -730,22 +757,22 @@ Discard:
|
|
|
730
757
|
|
|
731
758
|
**Email Validation Checklist**:
|
|
732
759
|
```
|
|
733
|
-
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
760
|
+
- Contains @ symbol
|
|
761
|
+
- Has valid domain extension
|
|
762
|
+
- Domain matches company website
|
|
763
|
+
- Not a role-based email (noreply, admin, etc.)
|
|
764
|
+
- Proper format (no spaces, special chars)
|
|
765
|
+
- Not a personal email (gmail, yahoo, etc. for B2B)
|
|
739
766
|
```
|
|
740
767
|
|
|
741
768
|
**Phone Validation Checklist**:
|
|
742
769
|
```
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
770
|
+
- Contains correct number of digits for region
|
|
771
|
+
- Has valid area/city code
|
|
772
|
+
- Not a fax number
|
|
773
|
+
- Not a toll-free number (for direct contact)
|
|
774
|
+
- Matches expected country code
|
|
775
|
+
- Includes extension if available
|
|
749
776
|
```
|
|
750
777
|
|
|
751
778
|
**Data Quality Scoring**:
|
|
@@ -772,7 +799,7 @@ Poor Quality (<50):
|
|
|
772
799
|
|
|
773
800
|
## Integration with LinkedIn Data
|
|
774
801
|
|
|
775
|
-
### Workflow: LinkedIn
|
|
802
|
+
### Workflow: LinkedIn -> Web Enrichment
|
|
776
803
|
|
|
777
804
|
**Pattern**: Use LinkedIn as source, enrich with web data
|
|
778
805
|
|
|
@@ -780,21 +807,21 @@ Poor Quality (<50):
|
|
|
780
807
|
|
|
781
808
|
1. **Find prospects on LinkedIn**
|
|
782
809
|
```
|
|
783
|
-
|
|
810
|
+
execute("linkedin", "search", "search_users", {"title": "<title>", "location": "<location>", "company_keywords": "<company>"})
|
|
784
811
|
```
|
|
785
812
|
|
|
786
813
|
2. **Get company websites**
|
|
787
814
|
```
|
|
788
815
|
For each prospect:
|
|
789
|
-
|
|
790
|
-
|
|
816
|
+
execute("linkedin", "company", "get", {"company": "<prospect.company>"})
|
|
817
|
+
-> Extract website URL
|
|
791
818
|
```
|
|
792
819
|
|
|
793
820
|
3. **Extract company contacts**
|
|
794
821
|
```
|
|
795
822
|
For each company website:
|
|
796
|
-
|
|
797
|
-
|
|
823
|
+
execute("webparser", "parse", "parse", {"url": "<website>/contact", "extract_contacts": true})
|
|
824
|
+
execute("webparser", "parse", "parse", {"url": "<website>/team", "extract_contacts": true})
|
|
798
825
|
```
|
|
799
826
|
|
|
800
827
|
4. **Match web contacts to LinkedIn**
|
|
@@ -803,7 +830,7 @@ For each email found on website:
|
|
|
803
830
|
If email pattern matches prospect name:
|
|
804
831
|
Assign email to LinkedIn prospect
|
|
805
832
|
Else:
|
|
806
|
-
Try
|
|
833
|
+
Try execute("linkedin", "email", "find", {"user": "<prospect>"})
|
|
807
834
|
```
|
|
808
835
|
|
|
809
836
|
5. **Build enriched prospect list**
|
|
@@ -813,6 +840,8 @@ Combine:
|
|
|
813
840
|
- Company website (phone, address)
|
|
814
841
|
- Direct email (from web or LinkedIn)
|
|
815
842
|
- Social profiles (from website)
|
|
843
|
+
|
|
844
|
+
Export via: export_data(cache_key, "csv")
|
|
816
845
|
```
|
|
817
846
|
|
|
818
847
|
**Expected Result**:
|
|
@@ -821,7 +850,7 @@ Combine:
|
|
|
821
850
|
- Verified company websites
|
|
822
851
|
- Full contact profiles ready for outreach
|
|
823
852
|
|
|
824
|
-
### Workflow: Web
|
|
853
|
+
### Workflow: Web -> LinkedIn Validation
|
|
825
854
|
|
|
826
855
|
**Pattern**: Use website as source, validate with LinkedIn
|
|
827
856
|
|
|
@@ -829,27 +858,27 @@ Combine:
|
|
|
829
858
|
|
|
830
859
|
1. **Extract team from website**
|
|
831
860
|
```
|
|
832
|
-
|
|
833
|
-
|
|
861
|
+
execute("webparser", "parse", "parse", {"url": "https://company.com/team", "extract_contacts": true})
|
|
862
|
+
-> Get names, titles, emails
|
|
834
863
|
```
|
|
835
864
|
|
|
836
865
|
2. **Search LinkedIn for each person**
|
|
837
866
|
```
|
|
838
867
|
For each team member:
|
|
839
|
-
|
|
840
|
-
first_name
|
|
841
|
-
last_name
|
|
842
|
-
company_keywords
|
|
843
|
-
)
|
|
868
|
+
execute("linkedin", "search", "search_users", {
|
|
869
|
+
"first_name": "<first>",
|
|
870
|
+
"last_name": "<last>",
|
|
871
|
+
"company_keywords": "<company>"
|
|
872
|
+
})
|
|
844
873
|
```
|
|
845
874
|
|
|
846
875
|
3. **Validate and enrich**
|
|
847
876
|
```
|
|
848
877
|
For each LinkedIn match:
|
|
849
|
-
|
|
850
|
-
|
|
851
|
-
|
|
852
|
-
|
|
878
|
+
execute("linkedin", "user", "get", {"user": "<username>"})
|
|
879
|
+
-> Verify title matches
|
|
880
|
+
-> Get full work history
|
|
881
|
+
-> Find additional contact methods
|
|
853
882
|
```
|
|
854
883
|
|
|
855
884
|
4. **Cross-reference data**
|
|
@@ -867,6 +896,8 @@ Keep prospects where:
|
|
|
867
896
|
- Title matches (or is recent)
|
|
868
897
|
- Still at company
|
|
869
898
|
- Email validated
|
|
899
|
+
|
|
900
|
+
Export via: export_data(cache_key, "csv")
|
|
870
901
|
```
|
|
871
902
|
|
|
872
903
|
**Expected Result**:
|
|
@@ -883,6 +914,8 @@ Keep prospects where:
|
|
|
883
914
|
2. **Parse in batches** of 5-10 websites at a time
|
|
884
915
|
3. **Prioritize high-value pages** (team, leadership) over generic contact pages
|
|
885
916
|
4. **Use LinkedIn first** for individual contacts, web scraping for company-level contacts
|
|
917
|
+
5. **Use get_page()** to paginate through large result sets without re-executing
|
|
918
|
+
6. **Use query_cache()** to filter and sort already-fetched data without new API calls
|
|
886
919
|
|
|
887
920
|
### Quality
|
|
888
921
|
|
|
@@ -904,6 +937,7 @@ Keep prospects where:
|
|
|
904
937
|
2. **Date stamp extractions** to know data freshness
|
|
905
938
|
3. **Deduplicate systematically** (same email from multiple pages)
|
|
906
939
|
4. **Categorize contacts** (by department, location, role)
|
|
940
|
+
5. **Export via export_data()** for permanent records and team sharing
|
|
907
941
|
|
|
908
942
|
---
|
|
909
943
|
|