如何爬取法院页面生成CSV?Colab Python爬虫问题求助
问题修复与完整代码
针对你遇到的三个问题,逐一修复并给出完整可运行的代码:
问题1:结果页面链接提取错误
原代码中item.find('a', first=True)是多余的,因为r.html.find('td.small a')已经直接定位到了链接元素。另外,页面返回的是相对路径,需要拼接完整域名。
修复后的链接提取函数:
def get_results_links(page): base_url = "https://www.tce.sp.gov.br" url = f"{base_url}/jurisprudencia/pesquisar?txtTdPalvs=munic%C3%ADpio+pessoal+37&txtExp=temporari&txtQqUma=admiss%C3%A3o+contrata%C3%A7%C3%A3o&txtNenhPalvs=&txtNumIni=&txtNumFim=&tipoBuscaTxt=Documento&_tipoBuscaTxt=on&quantTrechos=1&processo=&exercicio=&dataAutuacaoInicio=&dataAutuacaoFim=&dataPubInicio=01%2F01%2F2021&dataPubFim=31%2F12%2F2021&_relator=1&_auditor=1&_materia=1&tipoDocumento=2&_tipoDocumento=1&acao=Executa&offset={page}" links = [] r = s.get(url) results = r.html.find('td.small a') for item in results: full_link = base_url + item.attrs['href'] links.append(full_link) return links
问题2:仅返回一条结果
原代码所有字段都使用first=True,导致全部取第一个td.small的内容。需要根据第一个表格的行结构,按标签匹配对应字段:
问题3:提取第二个表格的指定文件信息
第二个表格包含行政裁决文件,需要筛选出类型为relatório/voto和acórdão的条目,按日期排序后取最早的,提取链接和日期。
完整修正代码
from requests_html import HTMLSession import csv from datetime import datetime s = HTMLSession() def get_results_links(page): base_url = "https://www.tce.sp.gov.br" url = f"{base_url}/jurisprudencia/pesquisar?txtTdPalvs=munic%C3%ADpio+pessoal+37&txtExp=temporari&txtQqUma=admiss%C3%A3o+contrata%C3%A7%C3%A3o&txtNenhPalvs=&txtNumIni=&txtNumFim=&tipoBuscaTxt=Documento&_tipoBuscaTxt=on&quantTrechos=1&processo=&exercicio=&dataAutuacaoInicio=&dataAutuacaoFim=&dataPubInicio=01%2F01%2F2021&dataPubFim=31%2F12%2F2021&_relator=1&_auditor=1&_materia=1&tipoDocumento=2&_tipoDocumento=1&acao=Executa&offset={page}" links = [] r = s.get(url) results = r.html.find('td.small a') for item in results: full_link = base_url + item.attrs['href'] links.append(full_link) return links def parse_result(url): r = s.get(url) # 初始化默认值 processo_data = { 'Nº do Processo': 'Não há', "Link do Processo": url, 'Data de Autuação': 'Não há', 'Parte 1': 'Não há', 'Parte 2': 'Não há', 'Exercício': 'Não há', 'Matéria': 'Não há', 'Objeto': 'Não há', 'Relator': 'Não há', 'Relatório/Voto': 'Não há', 'Data Relatório/Voto': 'Não há', 'Acórdão': 'Não há', 'Data Acórdão': 'Não há' } # 处理第一个表格:通用信息 info_table = r.html.find('table', first=True) if info_table: rows = info_table.find('tr') for row in rows: tds = row.find('td') if len(tds) >= 2: label = tds[0].text.strip() value = tds[1].text.strip() # 匹配对应表头字段 if label == 'Número do Processo': processo_data['Nº do Processo'] = value elif label == 'Data de Autuação': processo_data['Data de Autuação'] = value elif label == 'Parte 1': processo_data['Parte 1'] = value elif label == 'Parte 2': processo_data['Parte 2'] = value elif label == 'Exercício': processo_data['Exercício'] = value elif label == 'Matéria': processo_data['Matéria'] = value elif label == 'Objeto': processo_data['Objeto'] = value elif label == 'Relator': processo_data['Relator'] = value # 处理第二个表格:行政裁决文件 tables = r.html.find('table') if len(tables) >= 2: doc_table = tables[1] doc_rows = doc_table.find('tr')[1:] # 跳过表头行 relatorios = [] acordaoes = [] base_url = "https://www.tce.sp.gov.br" for row in doc_rows: cols = row.find('td') if len(cols) >= 4: doc_type = cols[1].text.strip().lower() doc_date = cols[2].text.strip() doc_link_elem = cols[3].find('a', first=True) if doc_link_elem: doc_link = base_url + doc_link_elem.attrs['href'] # 转换日期为datetime对象方便排序 try: date_obj = datetime.strptime(doc_date, '%d/%m/%Y') except ValueError: date_obj = datetime.max # 无效日期放最后 if 'relatório' in doc_type or 'voto' in doc_type: relatorios.append({'date': date_obj, 'link': doc_link, 'date_str': doc_date}) elif 'acórdão' in doc_type: acordaoes.append({'date': date_obj, 'link': doc_link, 'date_str': doc_date}) # 取最早的relatório/voto if relatorios: earliest_relatorio = sorted(relatorios, key=lambda x: x['date'])[0] processo_data['Relatório/Voto'] = earliest_relatorio['link'] processo_data['Data Relatório/Voto'] = earliest_relatorio['date_str'] # 取最早的acórdão if acordaoes: earliest_acordao = sorted(acordaoes, key=lambda x: x['date'])[0] processo_data['Acórdão'] = earliest_acordao['link'] processo_data['Data Acórdão'] = earliest_acordao['date_str'] return processo_data def save_csv(final): if not final: print("没有数据可保存") return # 按指定表头顺序排列 headers = [ 'Nº do Processo', 'Link do Processo', 'Data de Autuação', 'Parte 1', 'Parte 2', 'Exercício', 'Matéria', 'Objeto', 'Relator', 'Relatório/Voto', 'Data Relatório/Voto', 'Acórdão', 'Data Acórdão' ] with open('processos_tce.csv', 'w', newline='', encoding='utf-8') as f: dict_writer = csv.DictWriter(f, fieldnames=headers) dict_writer.writeheader() dict_writer.writerows(final) def main(): final = [] # 41页,offset从0到400,步长10 for page in range(0, 410, 10): print(f"正在抓取第 {page//10 + 1} 页") urls = get_results_links(page) if not urls: print(f"第 {page//10 + 1} 页没有找到结果链接") continue for idx, url in enumerate(urls): print(f"正在处理第 {page//10 + 1} 页的第 {idx+1} 个结果") try: data = parse_result(url) final.append(data) except Exception as e: print(f"处理链接 {url} 时出错: {str(e)}") continue print(f"当前已抓取 {len(final)} 条数据") # 每抓取一页保存一次,防止意外中断丢失数据 save_csv(final) print(f"抓取完成,共 {len(final)} 条数据") if __name__ == "__main__": main()
关键修复说明
- 链接提取:移除多余的
find('a'),拼接完整域名,确保生成可访问的链接。 - 通用信息提取:遍历第一个表格的每一行,根据标签匹配对应字段,不再只取第一个
td内容。 - 裁决文件提取:筛选目标类型文件,转换日期为可排序格式,取最早的条目并提取链接和日期。
- CSV保存:指定固定表头顺序,使用UTF-8编码避免乱码,每页抓取后保存一次数据。
内容的提问来源于stack exchange,提问作者João Pedro Rodrigues Oliveira
相关产品推荐
相关产品推荐

