Automated IP Extraction from FOFA Free Tier Using Python Requests and lxml

Step 1: Construct and Fetch the First Page

To retrieve initial search results from FOFA’s free interface, encode the query string in Base64 and issue an HTTP GET request. The example below searches for assets matching the app="thinkphp" fingerprint.

import requests
import base64

query = 'app="thinkphp"'
base_url = 'https://fofa.so/result?qbase64='
encoded_query = base64.b64encode(query.encode('utf-8')).decode('utf-8')
full_url = base_url + encoded_query

response = requests.get(full_url)
if response.status_code == 200:
    html_content = response.content
    print(html_content.decode('utf-8'))
else:
    print(f'Failed to fetch page: {response.status_code}')

Step 2: Parse and Extract IP-Host URLs from HTML

Use lxml.etree to parse the returned HTML and extract target URLs from anchor tags within .re-domain containers.

from lxml import etree

# Assuming `html_content` is available from previous step
tree = etree.HTML(html_content)
urls = tree.xpath('//div[@class="re-domain"]/a[@target="_blank"]/@href')

# Join into newline-separated string
formatted_urls = '\n'.join(urls)
print(formatted_urls)

# Append to file
with open('targets.txt', 'a', encoding='utf-8') as f:
    f.write(formatted_urls + '\n')

Step 3: Paginate with Authentication Headers

FOFA’s free tier requires valid session cookies to access mutliple pages. Below is a loop that iterates through five result pages using a custom header dictionary containing _fofapro_ars_session and other required cookies.

import time

cookies = {
    '_fofapro_ars_session': '1e1e66e681f5ca085635005',
    'Hm_lvt_9490413c5eebdadf757c2be2c816aedf': '1616029,161698533,16447,16171152',
    'search_history': 'app%3D%22thinkphp%22',
    'referer_url': '%2Fresult%3Fq%3Dapp%253D%2522thinkphp%2522%26qbase64%3DYXBwPSJ0aGlua3BocCI%253D%26file%3D%26file%3D',
    'Hm_lpvt_9490413c5eebdadf757c2be2c816aedf': '16175430'
}

base_search = 'app="thinkphp" && country="CN"'

for page_num in range(1, 6):
    encoded_search = base64.b64encode(base_search.encode('utf-8')).decode('utf-8')
    url = f'https://fofa.so/result?page={page_num}&qbase64={encoded_search}'
    
    try:
        res = requests.get(url, headers={'Cookie': '; '.join([f'{k}={v}' for k, v in cookies.items()])}, timeout=5)
        if res.status_code != 200:
            continue
            
        doc = etree.HTML(res.content)
        links = doc.xpath('//div[@class="re-domain"]/a[@target="_blank"]/@href')
        
        if links:
            batch_output = '\n'.join(links)
            print(f'Page {page_num}: extracted {len(links)} URLs')
            
            with open('targets.txt', 'a', encoding='utf-8') as out:
                out.write(batch_output + '\n')
                
        time.sleep(1)  # Respect rate limits
        
    except (requests.RequestException, etree.ParserError):
        continue

Note: Cookie values must be updated manually before execution. FOFA’s free plan restricts pagination depth and may throttle repeated requests without delays.

Tags: python fofa web-scraping automation security-tools

Posted on Thu, 24 Sep 2026 16:06:02 +0000 by lli2k5