ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

补天公益SRC主域名爬取

2021-10-10 11:04:23  阅读:396  来源: 互联网

标签:SRC 补天 url selenium 爬取 import page def browser


0x00 准备工作

  • 补天账号
  • python3运行环境
  • requests等第三方库

0x01 流程分析

分别查看专属SRC、企业SRC、公益SRC对应URL,发现没有变化。初步判断网站使用的是 Ajax,即异步的 JavaScript 和 XML。
在这里插入图片描述
进入公益SRC,查看不同页码对应的URL,仍然没有变化。
在这里插入图片描述
在这里插入图片描述
随机选取一个厂商,点击提交漏洞。发现URL发生变化,且找到了我们想要爬取的厂商名称和域名。
在这里插入图片描述

分析不同厂商提交漏洞页面的URL,发现每一个厂商都有其对应的 cid,关键是如何获取这一参数。

index_url = 'https://www.butian.net/Loo/submit?cid={c_id}'

Ajax是利用JavaScript在保证页面不被刷新、页面链接不被改变的情况下,与服务器进行数据交换并更新部分网页内容的技术。它实现了前后端的分离,降低了服务器直接渲染页面带来的压力。解析流程如下:

  • 发生请求:HttpXMLRequest
  • 解析内容:请求得到响应,触发 onreadystatechange 属性对应方法,返回相关内容。返回的内容可能是 HTML,也可能是 Json。如果返回的内容是 Json 的话,我们可以通过 JavaScript 进一步处理,对它进行解析和转化。
  • 渲染网页: 例如通过 docume.getElementById().innetHTML = XMLHttpRequest.responseText 对某元素内容进行更改,即DOM操作。

In a word,JavaScript 向服务器发送一个 Ajax 请求,请求得到响应后返回新的数据,数据通过 Ajax 加载,JavaScript 在后台调用 Ajax 函数接口得到数据,再对数据进行解析并渲染呈现。要想爬取页面信息,可以直接爬取 Ajax 接口获取数据。

0x02脚本编写

一、基于页码,爬取厂商CID列表:

def get_company_id(data):
    try:
        reponse = requests.post('https://www.butian.net/Reward/pub',data=data,timeout=(4,20))
        if reponse.status_code == 200:
            return reponse.json()
        logging.error('get invalid status_code %s while scraping %s',reponse.status_code,url)
    except requests.RequestException:
        logging.error('error occurred while scraping %s',url,exc_info=True)

def scrape_index_company_id(page):
    data={
    's': '1',
    'p': page,
    'token': ''
    }
    return get_company_id(data)

def scrape_parse_company_id(json):
    company_list = json['data']['list']
    page_num = json['data']['count']
    return company_list,page_num

Ajax 的请求接口通常包含加密参数,如 token、sign 等,但此处 token 为空,故直接使用 requests 即可。当 token 不为空时,通常有两种方法解决:

  • 深挖其中的逻辑,把 token 的逻辑完全找出来,再用 python 复现。
  • 直接通过 selenium 模拟浏览器的方式绕过这个过程。

二、基于厂商CID,爬取厂商名称和域名:

def get_domain(url): 
    try:
        reponse = requests.get(url,headers=headers)
        if reponse.status_code == 200:
            return reponse.text
        logging.error('get invalid status_code %s while scraping %s',reponse.status_code,url)
    except requests.RequestException:
        logging.error('error occurred while scraping %s',url,exc_info=True)

def scrape_index_domain(company_id):
    url = index_url.format(c_id=company_id)
    return get_domain(url)

def scrape_parse_domain(html):
    doc = pq(html)
    name = doc('input#inputCompy.input-xlarge').attr('value')
    try:
        url = re.search('type="text" name="host"[^>]+value="([^\"]+)"',html).group(1)
    except:
        url = "www.null.com"
    return name,url

三、保存厂商名称和域名:

def save_log(name,domain):
    obj = open("target.text",'a+')
    obj.write(name + "\t" + domain + "\n")
    obj.close()
  • r:只读,不创建(若文件不存在则报错)
  • r+:覆盖读写,不创建(若文件不存在则报错)
  • w:只写,新建(将原文件内容清空)
  • w+:读写,新建(将原文件内容清空)
  • a:附加写(若原文件不存在则创建)
  • a+:附加读写(若原文件不存在则创建)

0x03 多线程

threads = []
for page in range(1,188):
    time.sleep(10)
    thread = threading.Thread(target=main,args=(page,))
    thread.start()
    threads.append(thread)
for thread in threads:
    thread.join()

0x04 多进程

pool = multiprocessing.Pool(4)
pages = range(1,188)
pool.map(main,pages)
pool.close()
pool.join()

0x05 Extension

一、反屏蔽:

from selenium import webdriver
from selenium.webdriver import ChromeOptions

option = ChromeOptions()
option.add_experimental_option('excludeSwitchese',['enable-automation'])
option.add_experimental_option('useAutomationExtension',False)
browser = webdriver.Chrome(options=option)
browser.execute_cdp_cmd('Page.addScriptToEvaluateOnNewdocument',{'source':'Object.defineProperty(navigator,"webdriver",{get:()=>undefined})'})

二、无头模式:

from selenium import webdriver
from selenium import ChromeOptions

option = ChromeOptions()
option.add_argument('--headless')
browser = webdriver.Chrome(options=option)
browser.set_window_size(1366,768)

三、显式等待:

from selenium.webdriver.commom.by import By
from selenium.common.exceptions import TimeoutException
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

wait = WebDriverWait(browser,10)

def scrape_page(url,condition,locator):

四、隐式等待

browser.implicitly_wait(10)

0x06 Extension_Script

进入公益SRC页面:

def scrape_page(url,condition,locator):
    try:
        browser.get(url)
        wait.until(condition(locator))  
    except TimeoutException:
        logging.error('error occurred while sraping %s',url,exc_info=True)

def scrape_index():
    href = '/Reward/plan/1'
    url = urljoin(base_url,href)
    scrape_page(url,condition=EC.element_to_be_clickable,locator=(By.LINK_TEXT,'公益SRC'))

def parse_index():
        button = browser.find_element_by_link_text('公益SRC')
        button.click()

实现翻页:

def next_page():
    next = browser.find_element_by_class_name('next')
    wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR,'a.btn')))
    next.click()

基于翻页,爬取厂商提交漏洞页面的URL:

def main():
    scrape_index()
    parse_index()
    while True:
        wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR,'a.btn')))
        elements = browser.find_elements_by_css_selector('a.btn')
        for element in elements:
            href = element.get_attribute('href')
            print(href)
        time.sleep(5)
        next_page()

基于URL,爬取厂商名称和域名:

print(href) => get_domain(href)

The_fu11_extensi0n_scr1pt:

import time
import logging
from selenium import webdriver
from urllib.parse import urljoin
from selenium.webdriver.common.by import By
from selenium.common.exceptions import TimeoutException
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC

browser = webdriver.Chrome()

wait = WebDriverWait(browser,10)

base_url = 'https://www.butian.net'

logging.basicConfig(level=logging.INFO,format='%(asctime)s-%(levelname)s:%(message)s')

def scrape_page(url,condition,locator):
    try:
        browser.get(url)
        wait.until(condition(locator))  
    except TimeoutException:
        logging.error('error occurred while sraping %s',url,exc_info=True)

def scrape_index():
    href = '/Reward/plan/1'
    url = urljoin(base_url,href)
    scrape_page(url,condition=EC.element_to_be_clickable,locator=(By.LINK_TEXT,'公益SRC'))

def parse_index():
    button = browser.find_element_by_link_text('公益SRC')
    button.click()

def next_page():
    next = browser.find_element_by_class_name('next')
    try:
        next.click()
        wait.until(EC.element_to_be_clickable((By.CSS_SELECTOR,'a.btn')))
    except Exceptions as e:
        print("Exception found", format(e))

def main():
    scrape_index()
    parse_index()
    while True:
        elements = browser.find_elements_by_css_selector('a.btn')
        for element in elements:
            href = element.get_attribute('href')
            print(href)
        time.sleep(5)
        next_page()

if __name__=='__main__':
    main()

此部分作为拓展,当 token 不为空时,可以将该脚本与前面的 get_domain、scrape_parse_domain、save_log 等函数进行串联,从而实现对厂商名称和域名的爬取。

0x06 Summary

Informaintion garthering is the first and most critical step.

由于篇幅原因,笔者在上文中仅贴出了部分关键函数,不再对其进行串联。大家可以自行串联和完善,从而实现对目标域名多线程、多进程的爬取。

标签:SRC,补天,url,selenium,爬取,import,page,def,browser
来源: https://blog.csdn.net/qq_45927266/article/details/120613542

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有