You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何用Mechanize和BeautifulSoup实现指定矿产地网站分页数据爬取

实现矿物 occurrence 网站的分页数据爬取功能

我来帮你完善这个爬虫,搞定带搜索参数的分页数据获取功能。咱们一步步来,先补全代码里的细节,再实现核心的分页逻辑:

首先,先把初始化部分补全,确保浏览器模拟的配置正确:

import re
import mechanize
from bs4 import BeautifulSoup

class MineralDBScraper(object):
    def __init__(self):
        self.url = "http://dnre-mrne.gnb.ca/MineralOccurrence/default.aspx"
        self.br = mechanize.Browser()
        # 用完整的User-Agent避免被反爬拦截
        self.br.addheaders = [('User-agent', 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36')]
        # 配置浏览器行为,忽略robots.txt和自动处理刷新
        self.br.set_handle_robots(False)
        self.br.set_handle_refresh(False)

接下来实现搜索提交的方法,用来初始化第一页的搜索结果:

def search(self, ref_number="%"):
    """提交搜索表单,返回第一页的解析后数据"""
    # 打开目标页面
    self.br.open(self.url)
    
    # 选择页面上的第一个表单(也就是搜索表单)
    self.br.select_form(nr=0)
    
    # 注意:这里的表单字段名需要你自己去页面源码里确认!
    # 打开网页F12查看参考编号输入框的name属性,替换下面的字段名
    self.br.form['txtReferenceNumber'] = ref_number
    
    # 提交表单获取结果页
    response = self.br.submit()
    return self._parse_page(response.read())

然后写一个私有方法来解析单页的表格数据:

def _parse_page(self, html_content):
    """解析单页的表格,返回结构化的列表数据"""
    soup = BeautifulSoup(html_content, 'html.parser')
    # 同样,表格的id需要你去页面源码确认,这里是假设的id
    result_table = soup.find('table', {'id': 'gvMineralOccurrence'})
    if not result_table:
        return []
    
    # 跳过表头行,遍历数据行
    data_rows = result_table.find_all('tr')[1:]
    parsed_data = []
    for row in data_rows:
        cols = row.find_all('td')
        if cols:
            # 根据表格实际列顺序提取数据,这里是示例结构,你要按需调整
            item = {
                'reference_number': cols[0].text.strip(),
                'property_name': cols[1].text.strip(),
                'commodity': cols[2].text.strip(),
                # 其他字段根据页面表格的列数和内容补充
            }
            parsed_data.append(item)
    return parsed_data

核心的分页功能来了,实现获取下一页的方法:

def get_next_page(self):
    """获取下一页数据,没有下一页时返回空列表"""
    try:
        # 这里的分页按钮name属性同样需要你去页面源码确认!
        # 找下一页按钮的name,比如页面里可能是类似 'gvMineralOccurrence$ctl00$ctl04$ctl00$ctl01$ctl00$ctl02' 这样的名字
        response = self.br.submit(name='gvMineralOccurrence$ctl00$ctl04$ctl00$ctl01$ctl00$ctl02')
        return self._parse_page(response.read())
    except mechanize.FormNotFoundError:
        # 捕获找不到下一页按钮的异常,说明已经到最后一页了
        return []

最后给你一个完整的使用示例,方便测试:

if __name__ == "__main__":
    scraper = MineralDBScraper()
    # 初始搜索,用"%"作为参考编号获取全量结果
    first_page = scraper.search(ref_number="%")
    print(f"第一页数据共 {len(first_page)} 条")
    
    # 循环爬取所有分页
    all_mineral_data = first_page.copy()
    while True:
        next_page_data = scraper.get_next_page()
        if not next_page_data:
            print("已爬完所有页面")
            break
        print(f"获取到下一页,共 {len(next_page_data)} 条数据")
        all_mineral_data.extend(next_page_data)
    
    print(f"最终总共获取到 {len(all_mineral_data)} 条矿物 occurrence 数据")

关键注意事项

  • 字段名确认:一定要自己打开目标页面,用F12查看源码,确认搜索输入框、分页按钮的name属性,以及结果表格的id,示例里的名字都是假设的,必须替换成真实值才能正常工作。
  • 反爬防护:如果爬取频繁被拦截,可以在每次请求后加个延迟(比如time.sleep(2)),避免触发网站的反爬机制。
  • 页面结构变化:如果后续网站更新了页面布局,需要对应调整解析逻辑,比如表格的列顺序、元素的class/id等。

内容的提问来源于stack exchange,提问作者Umesh Pathak

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 08:00:32