【Python爬虫】Python编程艺术:轻松实现数据到Word文档的储存

【Python爬虫】Python编程艺术:轻松实现数据到Word文档的储存

在Python中,我们可能需要将抓取的数据在Word文档中存储和展示,可以使用一些第三方库如python-docx。这个库允许你创建、修改和提取Word文档的元素。请注意,python-docx只能处理.docx格式的文档。下面是如何使用这个库的详细步骤:

安装库:首先,通过命令pip install python-docx安装库。

创建文档:使用Document()类来创建一个新的Word文档或者打开一个现有的文档。

添加段落:通过add_paragraph()方法,你可以在文档中添加新的段落,段落会自动换行。

添加文本块:使用add_run()方法,在段落中添加文本块(Run对象),文本块不自动换行。

添加文本:通过add_text()方法,在文本块中添加文本,文本不支持插入换行符。

添加分隔符:使用add_break()方法,在文本块中添加分隔符,实现段落内的换行。

添加分页符:使用Document()类的add_page_break()方法,在文档中添加分页符。

保存文档:使用Document()类的save()方法保存你的文档。

以下是一段示例代码,展示了如何使用这些方法将数据存入Word文档:

#!/usr/bin/env python3

# -*- coding: utf-8 -*-

import requests

from bs4 import BeautifulSoup

import ssl

import pandas as pd

from urllib.parse import urljoin

import re

from docx import Document

from datetime import datetime

def create_unverified_context():

"""创建不验证服务器证书的HTTPS上下文"""

return ssl._create_unverified_context()

def get_soup(url, headers, context):

"""获取网页内容并返回BeautifulSoup对象"""

try:

# 确保URL以http开头

url = url.replace('https://', 'http://') if url.startswith('https://') else url

with requests.get(url, headers=headers, timeout=10, verify=False) as response:

response.raise_for_status()

return BeautifulSoup(response.content, "html.parser")

except requests.exceptions.HTTPError as e:

print(f"HTTP error: {e.response.status_code} - {e}")

except requests.exceptions.ConnectionError:

print("Error connecting to the server.")

except requests.exceptions.Timeout:

print("Request timed out.")

except requests.exceptions.RequestException as e:

print(f"Request error: {e}")

return None

def parse_article_soup(article_soup):

"""从BeautifulSoup对象中解析单页文章的详情"""

article_data = {

'正文': [],

'申请人': [],

'仲裁员': [],

'书记员': [],

'案由': None,

'日期': article_soup.find('meta',attrs={'name':'PubDate'}).get('content'),

'标题': article_soup.find('meta',attrs={'name':'ArticleTitle'}).get('content'),

'链接': article_soup.find('meta',attrs={'name':'Url'}).get('content'),

}

# 获取正文区域内属性style="text-align: center;"的

标签之后的所有元素

article_text_tags = article_soup.select('.news_cont_d_wrap p[style="text-align: center;"]:nth-child(2)~*')

# 获取所有标签的文本数据

i, n = 0, 0

for p in article_text_tags:

# 检查段落文本中是否包含特定关键词,并据此更新文章数据

text = re.sub(r'\s+', '', p.get_text(strip=True))

style_value = p.get('style')

# 获取案由

if text.startswith('案由'): #'案由' in re.sub(r'\s+','',p.get_text(strip=True))

article_data['案由'] = text

article_data['正文'].append(article_data['案由'])

n = i

# 获取仲裁员信息

elif text.startswith('仲裁员'):

article_data['仲裁员'].append(text)

elif text.startswith('书记员'):

article_data['书记员'].append(text)

# 处理表格

elif p.name == 'table':

rows = p.find_all('tr')

for row in rows:

columns = row.find_all('td')

# 提取单元格数据

row_data = [column.get_text(strip=True) for column in columns]

article_data['正文'].append(row_data)

# 获取案由之前的文本作为“申请人”,并过滤以“案号”开头的文本标签

elif n == 0 and text and not text.startswith('案号'):

article_data['申请人'].append(text)

# 获取案由之后的数据作为“正文”,并过滤

标签,和style_value以'right;'结尾的

标签

# style_value的值不是None的情况下,是以'right;'结尾

elif n != 0 and not p.find('table') and text and not (style_value and style_value.endswith('right;')):

article_data['正文'].append(text)

i += 1

return article_data

def parse_page_data(base_url, headers, context):

"""递归地爬取页面数据直到没有下一页"""

page_data = []

curr_page_url = base_url

# 使用while循环来实现递归爬取

while curr_page_url:

# 获取当前页的soup对象

soup = get_soup(curr_page_url, headers, context)

if not soup:

break # 如果soup为空,直接跳出循环

# 处理当前页的列表内数据

tag_list = soup.select('div.AllListCon a')

for tag in tag_list:

article_url = tag.get('href')

article_soup = get_soup(article_url, headers, context)

if article_soup:

page_data.append(parse_article_soup(article_soup))

# 查找下一页的链接

next_page = soup.find('a', class_='next')

if next_page:

curr_page_url = next_page.get('href') # 更新当前页面URL为下一页,继续循环

else:

break # 如果没有下一页,跳出循环

return page_data # 循环结束后返回data_list

# main函数

def main():

base_url = 'https://hrss.sz.gov.cn/ztfw/cjjy/wsgk/index.html'

headers = {'User-Agent': 'Mozilla/5.0 (compatible; YourBot/0.1)'}

context = create_unverified_context()

# 获取要储存数据的列表

data_list = parse_page_data(base_url, headers, context)

# 创建一个新的Word文档

doc = Document()

i = 0

# 添加数据段落

for data in data_list:

# 添加一个段落

paragraph = doc.add_paragraph()

# 向段落中添加运行

i += 1

paragraph.add_run(f"{i}、{data['日期'][:10]},{data['标题']}___{data['链接'][-12:-5]}").add_break()

# 正文

for text in data['正文']:

paragraph.add_run(text).add_break()

paragraph.add_run().add_break()

# 申请人

for text in data['申请人']:

paragraph.add_run(text).add_break()

paragraph.add_run().add_break()

# 仲裁员

paragraph.add_run(data['仲裁员'])

paragraph.add_run('。')

paragraph.add_run(data['书记员'])

# 在这里插入分页符

doc.add_page_break()

# 保存文档

doc_name = f'案例正文_{datetime.now().strftime("%Y%m%d.%H%M%S")}.docx'

doc.save(doc_name)

print(f'数据已保存到Word文档:{doc_name}')

if __name__ == "__main__":

main()

掌握python-docx:深入理解add_run()与add_text()的差异

在使用python-docx库进行Word文档操作时,理解add_run()和add_text()方法的区别至关重要。以下是对这两个方法以及其他相关方法的清晰解释:

add_paragraph()

创建段落:这个方法用于在Word文档中创建一个新的段落。

特点:每个段落可以可包含多个文本块(Run对象),可自定义样式。

样式多样性:段落的样式可以独立设置,段落之间有明显的间距(自带换行)。

add_run()

创建文本块:这个方法属于Paragraph对象,用于在段落中创建一个相同样式的文本块。

连续性:文本块在视觉上是连续的,通过 add_break() 方法可在 Run 对象后添加换行符。

样式多样性:每个 Run 对象允许独立设置样式(如字体、大小、加粗、颜色、下划线等)。Run 对象的样式设置应在 add_run() 之后进行。

add_text()

文本添加:这个方法专门用于向段落或文本块中添加文本内容。

参数限制:它只接受字符串(str)类型的参数,非字符串类型如data[0]将导致报错。

使用场景:通常在通过add_run()创建文本块后,使用add_text()向其中填充文本。

add_break()

换行操作:这个方法属于Run对象,用于在文本块后添加一个换行符,实现段落内分行。

分行不分段:添加的换行符仅在段落内形成新行,不会创建新的段落。

连续性:多次调用add_break(),也只会在文本块中实现一次换行,保持文本的连续性。

add_page_break()

分页符添加:这是Document类的实例方法,用于在文档的指定位置添加一个分页符。

页面控制:通过这个方法,用户可以精确控制文档的页面布局和内容分布。

通过这些方法,python-docx提供了强大的Word文档编辑能力,使得自动化文档生成和管理变得更加高效和灵活。

相关推荐

怎么查别人手机欠费多少(可以查别人手机话费余额吗)
几乎什么都敢吃的中国人,为什么很少有人吃猫肉?
365bet体育在线手机版

几乎什么都敢吃的中国人,为什么很少有人吃猫肉?

📅 01-17 👁️ 4454
连接了VPN还是上不了外网?一招教你轻松搞定!
365bet体育在线手机版

连接了VPN还是上不了外网?一招教你轻松搞定!

📅 10-26 👁️ 8412