JayBene1 commited on
Commit
0a31776
·
verified ·
1 Parent(s): 5371cb0

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +231 -110
app.py CHANGED
@@ -2,6 +2,8 @@ import gradio as gr
2
  import requests
3
  import re
4
  import json
 
 
5
  from urllib.parse import urlparse, urljoin
6
  import time
7
  import random
@@ -213,6 +215,8 @@ CONTACTS_DB = [
213
  def extract_domain(url):
214
  """Extract domain from URL"""
215
  try:
 
 
216
  parsed = urlparse(url)
217
  domain = parsed.netloc.lower()
218
  # Remove www. if present
@@ -245,15 +249,104 @@ def find_contacts_by_website(website_url):
245
  def simulate_website_scraping(url):
246
  """Simulate scraping a website and finding contact information"""
247
  # Add some delay to simulate real scraping
248
- time.sleep(random.uniform(1, 2))
249
 
250
  # Find matching contacts from our database
251
  contacts = find_contacts_by_website(url)
252
 
253
- # Only return contacts if we found exact matches
254
- # Don't return random contacts if no match found
255
  return contacts
256
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
257
  def search_website_contacts(website_url, max_results=10):
258
  """Main function to search for contacts on a website"""
259
  if not website_url:
@@ -274,30 +367,19 @@ def search_website_contacts(website_url, max_results=10):
274
  contacts = contacts[:max_results]
275
 
276
  # Format results
277
- results_text = f"📊 **CONTACT INTELLIGENCE REPORT**\n"
278
- results_text += f"🌐 **Website:** {website_url}\n"
279
- results_text += f"📈 **Contacts Found:** {len(contacts)}\n"
280
  results_text += f"{'='*60}\n\n"
281
 
282
- contact_data = []
283
  for i, contact in enumerate(contacts, 1):
284
- results_text += f"🏢 **CONTACT #{i}**\n"
285
- results_text += f"├─ **First Name:** {contact['first_name']}\n"
286
- results_text += f"├─ **Last Name:** {contact['last_name']}\n"
287
- results_text += f"├─ **Position:** {contact['job_title']}\n"
288
- results_text += f"├─ **Email:** {contact['email']}\n"
289
- results_text += f"├─ **Phone:** {contact['phone']}\n"
290
- results_text += f"└─ **Company:** {contact['company']}\n\n"
291
-
292
- # Prepare data for CSV/table format
293
- contact_data.append([
294
- contact['first_name'],
295
- contact['last_name'],
296
- contact['job_title'],
297
- contact['email'],
298
- contact['phone'],
299
- contact['company']
300
- ])
301
 
302
  # Create a simple table format for the second output
303
  table_text = "First Name,Last Name,Job Title,Email,Phone,Company\n"
@@ -314,9 +396,8 @@ def get_all_available_websites():
314
  websites = list(set([contact['website'] for contact in CONTACTS_DB]))
315
  return "\n".join(sorted(websites))
316
 
317
- # Custom CSS matching Kwekel Companies professional theme
318
  custom_css = """
319
- /* Kwekel-inspired Corporate Theme */
320
  .gradio-container {
321
  background: linear-gradient(135deg, #f8f9fa 0%, #e9ecef 100%);
322
  font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
@@ -369,14 +450,6 @@ custom_css = """
369
  font-weight: 600;
370
  }
371
 
372
- .quick-search-grid {
373
- display: grid;
374
- grid-template-columns: repeat(auto-fit, minmax(200px, 1fr));
375
- gap: 10px;
376
- margin: 20px 0;
377
- }
378
-
379
- /* Button Styling */
380
  .primary-btn {
381
  background: linear-gradient(135deg, #1e40af 0%, #3b82f6 100%);
382
  color: white;
@@ -410,7 +483,6 @@ custom_css = """
410
  background: #f8fafc;
411
  }
412
 
413
- /* Input Fields */
414
  .custom-input {
415
  border: 2px solid #d1d5db;
416
  border-radius: 8px;
@@ -424,7 +496,6 @@ custom_css = """
424
  box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.1);
425
  }
426
 
427
- /* Results Styling */
428
  .results-container {
429
  background: white;
430
  border: 1px solid #e5e7eb;
@@ -444,84 +515,128 @@ custom_css = """
444
  }
445
  """
446
 
447
- # Create Gradio interface with custom theme
448
- with gr.Blocks(css=custom_css, title="ZoomInfo Contact Discovery", theme=gr.themes.Base()) as app:
449
  gr.HTML("""
450
  <div class="main-header">
451
- <h1>ZoomInfo Contact Discovery</h1>
452
- <p>Professional Contact Discovery & Lead Generation Platform</p>
453
- <p style="font-size: 0.95em; opacity: 0.8;">Advanced website analysis for corporate intelligence gathering</p>
454
  </div>
455
  """)
456
 
457
- with gr.Row():
458
- with gr.Column(scale=3):
459
- gr.HTML('<div class="section-header"> SEARCH PARAMETERS</div>')
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
460
 
461
- website_input = gr.Textbox(
462
- label="Target Website URL",
463
- placeholder="Enter company website (e.g., techflowsolutions.com)",
464
- value="",
465
- elem_classes=["custom-input"]
466
- )
467
 
468
  with gr.Row():
469
- max_results = gr.Slider(
470
- minimum=1,
471
- maximum=20,
472
- value=8,
473
- step=1,
474
- label="📊 Maximum Results",
475
- elem_classes=["custom-input"]
476
  )
477
 
478
- search_btn = gr.Button(
479
- "🔍 EXECUTE SEARCH",
480
- variant="primary",
481
- size="lg",
482
- elem_classes=["primary-btn"]
 
483
  )
484
-
485
- with gr.Column(scale=2):
486
- gr.HTML("""
487
- <div class="tips-section">
488
- <h3>💼 CORPORATE INTELLIGENCE</h3>
489
- <ul style="margin: 10px 0; padding-left: 20px;">
490
- <li><strong>Real-Time Analysis:</strong> Live website scanning</li>
491
- <li><strong>Executive Contacts:</strong> C-level and key personnel</li>
492
- <li><strong>Direct Communications:</strong> Email & phone verification</li>
493
- <li><strong>Export Ready:</strong> CSV format for CRM integration</li>
494
- </ul>
495
- <div style="background: #1e40af; color: white; padding: 10px; border-radius: 5px; margin-top: 15px; text-align: center; font-weight: 600;">
496
- ENTERPRISE-GRADE CONTACT DISCOVERY
497
- </div>
498
- </div>
499
- """)
500
-
501
- gr.HTML('<div class="section-header">📈 INTELLIGENCE RESULTS</div>')
502
-
503
- with gr.Row():
504
- results_display = gr.Textbox(
505
- label="📋 Contact Intelligence Report",
506
- lines=18,
507
- max_lines=35,
508
- show_copy_button=True,
509
- elem_classes=["results-container"]
510
- )
511
 
512
- csv_output = gr.Textbox(
513
- label="📊 Export Data (CSV Format)",
514
- lines=18,
515
- max_lines=35,
516
- show_copy_button=True,
517
- elem_classes=["results-container"]
518
- )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
519
 
520
  # Sample websites section
521
- with gr.Accordion("🏢 CORPORATE DATABASE SAMPLES", open=False):
522
  gr.HTML('<div style="background: #f8fafc; padding: 15px; border-radius: 8px; border-left: 4px solid #1e40af;">')
523
  sample_websites = gr.Textbox(
524
- label="Available Corporate Websites in Database",
525
  value=get_all_available_websites(),
526
  lines=8,
527
  interactive=False,
@@ -530,19 +645,19 @@ with gr.Blocks(css=custom_css, title="ZoomInfo Contact Discovery", theme=gr.them
530
  gr.HTML('</div>')
531
 
532
  # Quick search buttons
533
- gr.HTML('<div class="section-header">⚡ QUICK ACCESS CORPORATE TARGETS</div>')
534
 
535
  with gr.Row():
536
- quick_btn1 = gr.Button("🔷 TechFlow Solutions", size="sm", elem_classes=["secondary-btn"])
537
- quick_btn2 = gr.Button("🌿 GreenLeaf Consulting", size="sm", elem_classes=["secondary-btn"])
538
- quick_btn3 = gr.Button("🎯 BlueSky Marketing", size="sm", elem_classes=["secondary-btn"])
539
- quick_btn4 = gr.Button("⚛️ Quantum Dynamics", size="sm", elem_classes=["secondary-btn"])
540
 
541
  with gr.Row():
542
- quick_btn5 = gr.Button("📦 Stellar Logistics", size="sm", elem_classes=["secondary-btn"])
543
- quick_btn6 = gr.Button("💰 Nexus Financial", size="sm", elem_classes=["secondary-btn"])
544
- quick_btn7 = gr.Button("🏥 Horizon Health", size="sm", elem_classes=["secondary-btn"])
545
- quick_btn8 = gr.Button("🏭 Phoenix Manufacturing", size="sm", elem_classes=["secondary-btn"])
546
 
547
  # Event handlers
548
  search_btn.click(
@@ -551,6 +666,12 @@ with gr.Blocks(css=custom_css, title="ZoomInfo Contact Discovery", theme=gr.them
551
  outputs=[results_display, csv_output]
552
  )
553
 
 
 
 
 
 
 
554
  # Quick search button handlers
555
  quick_btn1.click(lambda: "techflowsolutions.com", outputs=website_input)
556
  quick_btn2.click(lambda: "greenleafconsult.com", outputs=website_input)
@@ -570,14 +691,14 @@ with gr.Blocks(css=custom_css, title="ZoomInfo Contact Discovery", theme=gr.them
570
  ["quantumdynamics.org", 6]
571
  ],
572
  inputs=[website_input, max_results],
573
- label="🎯 Sample Corporate Searches"
574
  )
575
 
576
  # Footer
577
  gr.HTML("""
578
  <div style="text-align: center; padding: 30px 20px; background: linear-gradient(135deg, #64748b 0%, #475569 100%); color: white; border-radius: 15px; margin-top: 30px;">
579
- <h3 style="margin: 0 0 10px 0;">KWEKEL CONTACT INTELLIGENCE PLATFORM</h3>
580
- <p style="margin: 0; opacity: 0.9;">Professional-grade corporate contact discovery and lead generation technology</p>
581
  <p style="margin: 10px 0 0 0; font-size: 0.9em; opacity: 0.7;">Powered by advanced web intelligence algorithms</p>
582
  </div>
583
  """)
 
2
  import requests
3
  import re
4
  import json
5
+ import csv
6
+ import io
7
  from urllib.parse import urlparse, urljoin
8
  import time
9
  import random
 
215
  def extract_domain(url):
216
  """Extract domain from URL"""
217
  try:
218
+ if not url.startswith(('http://', 'https://')):
219
+ url = 'https://' + url
220
  parsed = urlparse(url)
221
  domain = parsed.netloc.lower()
222
  # Remove www. if present
 
249
  def simulate_website_scraping(url):
250
  """Simulate scraping a website and finding contact information"""
251
  # Add some delay to simulate real scraping
252
+ time.sleep(random.uniform(0.5, 1))
253
 
254
  # Find matching contacts from our database
255
  contacts = find_contacts_by_website(url)
256
 
 
 
257
  return contacts
258
 
259
+ def parse_csv_file(file_content):
260
+ """Parse CSV file and extract website URLs"""
261
+ websites = []
262
+ try:
263
+ # Decode file content
264
+ content = file_content.decode('utf-8')
265
+
266
+ # Parse CSV
267
+ csv_reader = csv.DictReader(io.StringIO(content))
268
+
269
+ # Look for common website column names
270
+ website_columns = ['website', 'url', 'domain', 'site', 'web', 'homepage']
271
+
272
+ for row in csv_reader:
273
+ # Find website column
274
+ website_url = None
275
+ for col_name in row.keys():
276
+ if col_name.lower() in website_columns:
277
+ website_url = row[col_name]
278
+ break
279
+
280
+ if website_url and website_url.strip():
281
+ websites.append(website_url.strip())
282
+
283
+ return websites
284
+ except Exception as e:
285
+ print(f"Error parsing CSV: {e}")
286
+ return []
287
+
288
+ def search_csv_websites(csv_file, max_results=10):
289
+ """Search for contacts from websites listed in CSV file"""
290
+ if csv_file is None:
291
+ return "Please upload a CSV file", ""
292
+
293
+ try:
294
+ # Parse CSV file
295
+ websites = parse_csv_file(csv_file)
296
+
297
+ if not websites:
298
+ return "No websites found in CSV file. Please ensure your CSV has a column named 'website', 'url', or 'domain'.", ""
299
+
300
+ all_contacts = []
301
+ processed_websites = []
302
+
303
+ # Search each website
304
+ for website in websites[:20]: # Limit to first 20 websites
305
+ contacts = simulate_website_scraping(website)
306
+ if contacts:
307
+ all_contacts.extend(contacts)
308
+ processed_websites.append(website)
309
+
310
+ # Remove duplicates based on email
311
+ unique_contacts = []
312
+ seen_emails = set()
313
+ for contact in all_contacts:
314
+ if contact['email'] not in seen_emails:
315
+ unique_contacts.append(contact)
316
+ seen_emails.add(contact['email'])
317
+
318
+ # Limit results
319
+ unique_contacts = unique_contacts[:max_results]
320
+
321
+ if not unique_contacts:
322
+ return f"No contacts found for the {len(websites)} websites in the CSV file.", ""
323
+
324
+ # Format results
325
+ results_text = f"CONTACT DISCOVERY REPORT\n"
326
+ results_text += f"Websites Processed: {len(processed_websites)}\n"
327
+ results_text += f"Total Websites in CSV: {len(websites)}\n"
328
+ results_text += f"Unique Contacts Found: {len(unique_contacts)}\n"
329
+ results_text += f"{'='*60}\n\n"
330
+
331
+ for i, contact in enumerate(unique_contacts, 1):
332
+ results_text += f"CONTACT #{i}\n"
333
+ results_text += f"Name: {contact['first_name']} {contact['last_name']}\n"
334
+ results_text += f"Position: {contact['job_title']}\n"
335
+ results_text += f"Email: {contact['email']}\n"
336
+ results_text += f"Phone: {contact['phone']}\n"
337
+ results_text += f"Company: {contact['company']}\n"
338
+ results_text += f"Website: {contact['website']}\n\n"
339
+
340
+ # Create CSV output
341
+ csv_output = "First Name,Last Name,Job Title,Email,Phone,Company,Website\n"
342
+ for contact in unique_contacts:
343
+ csv_output += f"{contact['first_name']},{contact['last_name']},{contact['job_title']},{contact['email']},{contact['phone']},{contact['company']},{contact['website']}\n"
344
+
345
+ return results_text, csv_output
346
+
347
+ except Exception as e:
348
+ return f"Error processing CSV file: {str(e)}", ""
349
+
350
  def search_website_contacts(website_url, max_results=10):
351
  """Main function to search for contacts on a website"""
352
  if not website_url:
 
367
  contacts = contacts[:max_results]
368
 
369
  # Format results
370
+ results_text = f"CONTACT INTELLIGENCE REPORT\n"
371
+ results_text += f"Website: {website_url}\n"
372
+ results_text += f"Contacts Found: {len(contacts)}\n"
373
  results_text += f"{'='*60}\n\n"
374
 
 
375
  for i, contact in enumerate(contacts, 1):
376
+ results_text += f"CONTACT #{i}\n"
377
+ results_text += f"First Name: {contact['first_name']}\n"
378
+ results_text += f"Last Name: {contact['last_name']}\n"
379
+ results_text += f"Position: {contact['job_title']}\n"
380
+ results_text += f"Email: {contact['email']}\n"
381
+ results_text += f"Phone: {contact['phone']}\n"
382
+ results_text += f"Company: {contact['company']}\n\n"
 
 
 
 
 
 
 
 
 
 
383
 
384
  # Create a simple table format for the second output
385
  table_text = "First Name,Last Name,Job Title,Email,Phone,Company\n"
 
396
  websites = list(set([contact['website'] for contact in CONTACTS_DB]))
397
  return "\n".join(sorted(websites))
398
 
399
+ # Custom CSS
400
  custom_css = """
 
401
  .gradio-container {
402
  background: linear-gradient(135deg, #f8f9fa 0%, #e9ecef 100%);
403
  font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
 
450
  font-weight: 600;
451
  }
452
 
 
 
 
 
 
 
 
 
453
  .primary-btn {
454
  background: linear-gradient(135deg, #1e40af 0%, #3b82f6 100%);
455
  color: white;
 
483
  background: #f8fafc;
484
  }
485
 
 
486
  .custom-input {
487
  border: 2px solid #d1d5db;
488
  border-radius: 8px;
 
496
  box-shadow: 0 0 0 3px rgba(59, 130, 246, 0.1);
497
  }
498
 
 
499
  .results-container {
500
  background: white;
501
  border: 1px solid #e5e7eb;
 
515
  }
516
  """
517
 
518
+ # Create Gradio interface
519
+ with gr.Blocks(css=custom_css, title="Contact Discovery Platform", theme=gr.themes.Base()) as app:
520
  gr.HTML("""
521
  <div class="main-header">
522
+ <h1>Contact Discovery Platform</h1>
523
+ <p>Professional Contact Discovery & Lead Generation Tool</p>
524
+ <p style="font-size: 0.95em; opacity: 0.8;">Advanced website analysis for contact intelligence gathering</p>
525
  </div>
526
  """)
527
 
528
+ with gr.Tabs():
529
+ # Single Website Search Tab
530
+ with gr.TabItem("Single Website Search"):
531
+ with gr.Row():
532
+ with gr.Column(scale=2):
533
+ gr.HTML('<div class="section-header">Search Parameters</div>')
534
+
535
+ website_input = gr.Textbox(
536
+ label="Target Website URL",
537
+ placeholder="Enter company website (e.g., techflowsolutions.com)",
538
+ value="",
539
+ elem_classes=["custom-input"]
540
+ )
541
+
542
+ with gr.Row():
543
+ max_results = gr.Slider(
544
+ minimum=1,
545
+ maximum=20,
546
+ value=8,
547
+ step=1,
548
+ label="Maximum Results",
549
+ elem_classes=["custom-input"]
550
+ )
551
+
552
+ search_btn = gr.Button(
553
+ "Execute Search",
554
+ variant="primary",
555
+ size="lg",
556
+ elem_classes=["primary-btn"]
557
+ )
558
 
559
+ gr.HTML('<div class="section-header">Search Results</div>')
 
 
 
 
 
560
 
561
  with gr.Row():
562
+ results_display = gr.Textbox(
563
+ label="Contact Intelligence Report",
564
+ lines=18,
565
+ max_lines=35,
566
+ show_copy_button=True,
567
+ elem_classes=["results-container"]
 
568
  )
569
 
570
+ csv_output = gr.Textbox(
571
+ label="Export Data (CSV Format)",
572
+ lines=18,
573
+ max_lines=35,
574
+ show_copy_button=True,
575
+ elem_classes=["results-container"]
576
  )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
577
 
578
+ # CSV Upload Tab
579
+ with gr.TabItem("CSV Bulk Search"):
580
+ with gr.Row():
581
+ with gr.Column(scale=2):
582
+ gr.HTML('<div class="section-header">CSV Upload</div>')
583
+
584
+ csv_file = gr.File(
585
+ label="Upload CSV File",
586
+ file_types=[".csv"],
587
+ elem_classes=["custom-input"]
588
+ )
589
+
590
+ gr.HTML("""
591
+ <div style="background: #f8fafc; padding: 15px; border-radius: 8px; border-left: 4px solid #1e40af; margin: 10px 0;">
592
+ <strong>CSV Format Requirements:</strong><br>
593
+ • Include a column named 'website', 'url', or 'domain'<br>
594
+ • One website per row<br>
595
+ • Example: techflowsolutions.com, greenleafconsult.com
596
+ </div>
597
+ """)
598
+
599
+ with gr.Row():
600
+ csv_max_results = gr.Slider(
601
+ minimum=1,
602
+ maximum=50,
603
+ value=20,
604
+ step=1,
605
+ label="Maximum Results",
606
+ elem_classes=["custom-input"]
607
+ )
608
+
609
+ csv_search_btn = gr.Button(
610
+ "Process CSV",
611
+ variant="primary",
612
+ size="lg",
613
+ elem_classes=["primary-btn"]
614
+ )
615
+
616
+ gr.HTML('<div class="section-header">CSV Results</div>')
617
+
618
+ with gr.Row():
619
+ csv_results_display = gr.Textbox(
620
+ label="CSV Processing Report",
621
+ lines=18,
622
+ max_lines=35,
623
+ show_copy_button=True,
624
+ elem_classes=["results-container"]
625
+ )
626
+
627
+ csv_export_output = gr.Textbox(
628
+ label="Export Data (CSV Format)",
629
+ lines=18,
630
+ max_lines=35,
631
+ show_copy_button=True,
632
+ elem_classes=["results-container"]
633
+ )
634
 
635
  # Sample websites section
636
+ with gr.Accordion("Sample Websites Database", open=False):
637
  gr.HTML('<div style="background: #f8fafc; padding: 15px; border-radius: 8px; border-left: 4px solid #1e40af;">')
638
  sample_websites = gr.Textbox(
639
+ label="Available Websites in Database",
640
  value=get_all_available_websites(),
641
  lines=8,
642
  interactive=False,
 
645
  gr.HTML('</div>')
646
 
647
  # Quick search buttons
648
+ gr.HTML('<div class="section-header">Quick Access Sample Websites</div>')
649
 
650
  with gr.Row():
651
+ quick_btn1 = gr.Button("TechFlow Solutions", size="sm", elem_classes=["secondary-btn"])
652
+ quick_btn2 = gr.Button("GreenLeaf Consulting", size="sm", elem_classes=["secondary-btn"])
653
+ quick_btn3 = gr.Button("BlueSky Marketing", size="sm", elem_classes=["secondary-btn"])
654
+ quick_btn4 = gr.Button("Quantum Dynamics", size="sm", elem_classes=["secondary-btn"])
655
 
656
  with gr.Row():
657
+ quick_btn5 = gr.Button("Stellar Logistics", size="sm", elem_classes=["secondary-btn"])
658
+ quick_btn6 = gr.Button("Nexus Financial", size="sm", elem_classes=["secondary-btn"])
659
+ quick_btn7 = gr.Button("Horizon Health", size="sm", elem_classes=["secondary-btn"])
660
+ quick_btn8 = gr.Button("Phoenix Manufacturing", size="sm", elem_classes=["secondary-btn"])
661
 
662
  # Event handlers
663
  search_btn.click(
 
666
  outputs=[results_display, csv_output]
667
  )
668
 
669
+ csv_search_btn.click(
670
+ fn=search_csv_websites,
671
+ inputs=[csv_file, csv_max_results],
672
+ outputs=[csv_results_display, csv_export_output]
673
+ )
674
+
675
  # Quick search button handlers
676
  quick_btn1.click(lambda: "techflowsolutions.com", outputs=website_input)
677
  quick_btn2.click(lambda: "greenleafconsult.com", outputs=website_input)
 
691
  ["quantumdynamics.org", 6]
692
  ],
693
  inputs=[website_input, max_results],
694
+ label="Sample Searches"
695
  )
696
 
697
  # Footer
698
  gr.HTML("""
699
  <div style="text-align: center; padding: 30px 20px; background: linear-gradient(135deg, #64748b 0%, #475569 100%); color: white; border-radius: 15px; margin-top: 30px;">
700
+ <h3 style="margin: 0 0 10px 0;">Contact Intelligence Platform</h3>
701
+ <p style="margin: 0; opacity: 0.9;">Professional-grade contact discovery and lead generation technology</p>
702
  <p style="margin: 10px 0 0 0; font-size: 0.9em; opacity: 0.7;">Powered by advanced web intelligence algorithms</p>
703
  </div>
704
  """)