这是一个使用 Python 编写的百度搜索工具,提供手动和自动两种模式,可以爬取网页并索引,并在本地进行搜索。

手动模式

  • 输入关键词和爬取页数。
  • 点击“爬取并索引”按钮,程序会爬取指定页数的百度搜索结果,并保存到本地文件。
  • 输入搜索关键词,点击“搜索”按钮,程序会在本地文件搜索匹配结果并显示。

自动模式

  • 输入关键词、爬取页数和结果条数限制。
  • 点击“爬取并索引”按钮,程序会爬取指定页数的百度搜索结果,并保存到本地文件。
  • 此外,程序还会自动拆分首次搜索结果的标题文本,使用拆分后的字作为新的关键词进行扩展搜索,直到达到结果条数限制。
  • 输入搜索关键词,点击“搜索”按钮,程序会在本地文件搜索匹配结果并显示。

代码示例:

import requests
from bs4 import BeautifulSoup
import time
import tkinter as tk
from tkinter import ttk
import webbrowser
import random
import os
import re


def get_random_user_agent():
    user_agents = [
        'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.124 Safari/537.36',
        'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/90.0.4430.212 Safari/537.36',
        'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/89.0.4389.82 Safari/537.36',
    ]
    return random.choice(user_agents)


def crawl_baidu(keyword, page_limit):
    headers = {
        'User-Agent': get_random_user_agent()
    }

    results = []
    for page in range(1, page_limit + 1):
        url = f'https://www.baidu.com/s?wd={keyword}&pn={(page - 1) * 10}'

        # 添加随机延迟
        delay = random.uniform(0.5, 1.0)
        time.sleep(delay)

        response = requests.get(url, headers=headers)
        soup = BeautifulSoup(response.text, 'html.parser')

        for result in soup.find_all('div', class_='result'):
            result_title = result.find('h3').get_text()
            result_url = result.find('a')['href']
            results.append((result_title, result_url))

    return results


def open_url(url):
    webbrowser.open(url)


def crawl_and_index_manual():
    keywords = re.split(r'[,,\s]+', entry_keywords_manual.get())  # 获取关键词列表
    page_limit = int(entry_pages_manual.get())  # 获取指定的爬取页数

    # 创建文件夹用于保存网页文件
    if not os.path.exists('webpages'):
        os.makedirs('webpages')

    result_text_manual.delete('1.0', tk.END)

    # 爬取并保存网页文件
    total_results = []
    for keyword in keywords:
        search_results = crawl_baidu(keyword, page_limit)
        if len(search_results) > 0:
            total_results.extend(search_results)
            file_name = f'webpages/{keyword}.html'
            with open(file_name, 'w', encoding='utf-8') as file:
                for title, url in search_results:
                    file.write(f'{title}\n')
                    file.write(f'{url}\n')
                file.write('\n')
            result_text_manual.insert(tk.END, f'关键词 '{keyword}' 搜索完成,保存了 {len(search_results)} 条结果\n')
        else:
            result_text_manual.insert(tk.END, f'关键词 '{keyword}' 没有搜索结果\n')

    result_text_manual.insert(tk.END, f'\n共搜索并保存了 {len(total_results)} 条结果\n')


def search_local_manual():
    keyword = entry_search_manual.get()
    result_text_manual.delete('1.0', tk.END)

    # 遍历网页文件,搜索匹配的结果
    for file_name in os.listdir('webpages'):
        with open(f'webpages/{file_name}', 'r', encoding='utf-8') as file:
            lines = file.readlines()

            # 确保行数足够
            if len(lines) < 2:
                continue

            found_results = {}
            for i in range(0, len(lines), 2):
                if i + 1 >= len(lines):
                    break

                title = lines[i].strip()
                url = lines[i + 1].strip()
                if keyword.lower() in title.lower() or keyword.lower() in url.lower():
                    found_results[len(found_results) + 1] = (title, url)

            if len(found_results) > 0:
                result_text_manual.insert(tk.END, f'搜索结果 - {file_name[:-5]}:\n\n', 'title')
                for index, (title, url) in found_results.items():
                    result_text_manual.insert(tk.END, f'{title}\n', 'found_title')
                    result_text_manual.insert(tk.END, f'{url}\n', f'link{index}')
                    result_text_manual.tag_configure(f'link{index}', foreground='blue', underline=True)
                    result_text_manual.tag_bind(f'link{index}', '<Button-1>', lambda event, url=url: open_url(url))
                result_text_manual.insert(tk.END, '\n')

    if result_text_manual.get('1.0', tk.END) == '\n':
        result_text_manual.insert(tk.END, '没有搜索结果\n')


def crawl_and_index_auto():
    keywords = re.split(r'[,,\s]+', entry_keywords_auto.get())  # 获取关键词列表
    page_limit = int(entry_pages_auto.get())  # 获取指定的爬取页数
    result_limit = int(entry_result_limit.get())  # 获取结果条数限制

    # 创建文件夹用于保存网页文件
    if not os.path.exists('webpages'):
        os.makedirs('webpages')

    result_text_auto.delete('1.0', tk.END)

    # 爬取并保存网页文件
    total_results = []
    for keyword in keywords:
        search_results = crawl_baidu(keyword, page_limit)
        if len(search_results) > 0:
            total_results.extend(search_results)
            file_name = f'webpages/{keyword}.html'
            with open(file_name, 'w', encoding='utf-8') as file:
                for title, url in search_results:
                    file.write(f'{title}\n')
                    file.write(f'{url}\n')
                file.write('\n')
            result_text_auto.insert(tk.END, f'关键词 '{keyword}' 搜索完成,保存了 {len(search_results)} 条结果\n')
        else:
            result_text_auto.insert(tk.END, f'关键词 '{keyword}' 没有搜索结果\n')

        # 对于每个关键词的首次搜索结果,拆分标题文本,使用拆分后的字作为新的关键词进行搜索
        if len(search_results) > 0:
            new_keywords = []
            for title, _ in search_results:
                new_keywords.extend(list(title))
            new_keywords = list(set(new_keywords))  # 去重

            # 对于新的关键词进行搜索
            for new_keyword in new_keywords:
                if len(total_results) >= result_limit:
                    break
                search_results = crawl_baidu(new_keyword, page_limit)
                if len(search_results) > 0:
                    total_results.extend(search_results)
                    file_name = f'webpages/{new_keyword}.html'
                    with open(file_name, 'w', encoding='utf-8') as file:
                        for title, url in search_results:
                            file.write(f'{title}\n')
                            file.write(f'{url}\n')
                        file.write('\n')
                    result_text_auto.insert(tk.END, f'关键词 '{new_keyword}' 搜索完成,保存了 {len(search_results)} 条结果\n')
                else:
                    result_text_auto.insert(tk.END, f'关键词 '{new_keyword}' 没有搜索结果\n')

                if len(total_results) >= result_limit:
                    break

    result_text_auto.insert(tk.END, f'\n共搜索并保存了 {len(total_results)} 条结果\n')


def search_local_auto():
    keyword = entry_search_auto.get()
    result_text_auto.delete('1.0', tk.END)

    # 遍历网页文件,搜索匹配的结果
    for file_name in os.listdir('webpages'):
        with open(f'webpages/{file_name}', 'r', encoding='utf-8') as file:
            lines = file.readlines()

            # 确保行数足够
            if len(lines) < 2:
                continue

            found_results = {}
            for i in range(0, len(lines), 2):
                if i + 1 >= len(lines):
                    break

                title = lines[i].strip()
                url = lines[i + 1].strip()
                if keyword.lower() in title.lower() or keyword.lower() in url.lower():
                    found_results[len(found_results) + 1] = (title, url)

            if len(found_results) > 0:
                result_text_auto.insert(tk.END, f'搜索结果 - {file_name[:-5]}:\n\n', 'title')
                for index, (title, url) in found_results.items():
                    result_text_auto.insert(tk.END, f'{title}\n', 'found_title')
                    result_text_auto.insert(tk.END, f'{url}\n', f'link{index}')
                    result_text_auto.tag_configure(f'link{index}', foreground='blue', underline=True)
                    result_text_auto.tag_bind(f'link{index}', '<Button-1>', lambda event, url=url: open_url(url))
                result_text_auto.insert(tk.END, '\n')

    if result_text_auto.get('1.0', tk.END) == '\n':
        result_text_auto.insert(tk.END, '没有搜索结果\n')


# 创建总体UI界面
window = tk.Tk()
window.title('百度搜索')
window.geometry('800x600')

# 创建选项卡控件
tab_control = ttk.Notebook(window)

# 添加手动模式选项卡
tab_manual = ttk.Frame(tab_control)
tab_control.add(tab_manual, text='手动模式')
tab_control.pack(expand=1, fill='both')

# 添加自动模式选项卡
tab_auto = ttk.Frame(tab_control)
tab_control.add(tab_auto, text='自动模式')
tab_control.pack(expand=1, fill='both')

# 在手动模式选项卡中添加组件
label_manual = tk.Label(tab_manual, text='手动模式')
label_manual.pack()

label_keywords_manual = tk.Label(tab_manual, text='请输入关键词(用逗号或空格隔开):')
label_keywords_manual.pack()

entry_keywords_manual = tk.Entry(tab_manual)
entry_keywords_manual.pack()

label_pages_manual = tk.Label(tab_manual, text='请输入爬取页数:')
label_pages_manual.pack()

entry_pages_manual = tk.Entry(tab_manual)
entry_pages_manual.pack()

crawl_button_manual = tk.Button(tab_manual, text='爬取并索引', command=crawl_and_index_manual)
crawl_button_manual.pack()

label_search_manual = tk.Label(tab_manual, text='请输入搜索关键词:')
label_search_manual.pack()

entry_search_manual = tk.Entry(tab_manual)
entry_search_manual.pack()

search_button_manual = tk.Button(tab_manual, text='搜索', command=search_local_manual)
search_button_manual.pack()

scrollbar_manual = tk.Scrollbar(tab_manual)
scrollbar_manual.pack(side=tk.RIGHT, fill=tk.Y)

result_text_manual = tk.Text(tab_manual, yscrollcommand=scrollbar_manual.set)
result_text_manual.pack(fill=tk.BOTH)

scrollbar_manual.config(command=result_text_manual.yview)


# 在自动模式选项卡中添加组件
label_auto = tk.Label(tab_auto, text='自动模式')
label_auto.pack()

label_keywords_auto = tk.Label(tab_auto, text='请输入关键词(用逗号或空格隔开):')
label_keywords_auto.pack()

entry_keywords_auto = tk.Entry(tab_auto)
entry_keywords_auto.pack()

label_pages_auto = tk.Label(tab_auto, text='请输入爬取页数:')
label_pages_auto.pack()

entry_pages_auto = tk.Entry(tab_auto)
entry_pages_auto.pack()

label_result_limit = tk.Label(tab_auto, text='请输入结果条数限制:')
label_result_limit.pack()

entry_result_limit = tk.Entry(tab_auto)
entry_result_limit.pack()

crawl_button_auto = tk.Button(tab_auto, text='爬取并索引', command=crawl_and_index_auto)
crawl_button_auto.pack()

label_search_auto = tk.Label(tab_auto, text='请输入搜索关键词:')
label_search_auto.pack()

entry_search_auto = tk.Entry(tab_auto)
entry_search_auto.pack()

search_button_auto = tk.Button(tab_auto, text='搜索', command=search_local_auto)
search_button_auto.pack()

scrollbar_auto = tk.Scrollbar(tab_auto)
scrollbar_auto.pack(side=tk.RIGHT, fill=tk.Y)

result_text_auto = tk.Text(tab_auto, yscrollcommand=scrollbar_auto.set)
result_text_auto.pack(fill=tk.BOTH)

scrollbar_auto.config(command=result_text_auto.yview)


# 运行主界面
window.mainloop()

使用方法:

  1. 将代码保存为一个Python文件,例如baidu_search.py
  2. 运行该文件。
  3. 在弹出的窗口中选择手动或自动模式,并按照提示输入相关信息。
  4. 点击“爬取并索引”按钮,程序会开始爬取网页并保存到本地文件。
  5. 输入搜索关键词,点击“搜索”按钮,程序会在本地文件搜索匹配结果并显示。

注意:

  • 该程序使用Tkinter库创建图形界面,请确保已安装Tkinter。
  • 程序使用requests库和BeautifulSoup库进行网页爬取,请确保已安装这两个库。
  • 该程序仅用于学习和研究目的,请勿用于任何违法或侵权行为。
  • 由于百度反爬机制,程序可能会出现无法爬取数据或被封禁的情况,请谨慎使用。
  • 该程序可能需要较长的运行时间,请耐心等待。

未来改进方向:

  • 添加对更多搜索引擎的支持。
  • 优化爬取效率和数据处理速度。
  • 添加数据分析功能,例如对搜索结果进行关键词提取和聚类。
  • 构建更完善的本地索引系统,支持更快速的搜索。

希望该工具能帮助您更好地理解和使用百度搜索数据。

Python 百度搜索工具:手动/自动模式,爬取网页并本地搜索

原文地址: https://www.cveoy.top/t/topic/vWa 著作权归作者所有。请勿转载和采集!

免费AI点我,无需注册和登录