基础
通常会用到一系列工具和库来处理不同阶段的任务。
请求发送(Fetching)
- requests: 最流行的 HTTP 客户端库,用于发送同步的 HTTP 请求。
- httpx: 一个支持 HTTP/2 和异步请求的现代 HTTP 客户端库。
- aiohttp: 用于异步请求的库,适用于处理大量并发的 HTTP 请求。
HTML 解析(Parsing)
- BeautifulSoup: 功能强大的库,可以从 HTML 或 XML 文件中提取数据。
- lxml: 高效的 XML 和 HTML 解析库,速度通常比 BeautifulSoup 快,但使用起来也更复杂。
数据提取(Extraction)
- re: Python 的正则表达式模块,用于复杂文本数据的提取。
- parsel: 专门为网页数据提取设计的库,支持 CSS 和 XPath 选择器。
动态渲染页面处理(Dynamic Content)
- 使用 selenium 或 playwright 结合无头浏览器(如 Chrome 的无头模式)可以执行 JavaScript 从而获取动态加载的内容。
- Splash: 一个 JavaScript 渲染服务,与 Scrapy 结合使用,可以处理动态渲染的网站数据。
实践
主方法
if __name__ == '__main__':
url_list = read_url_list_from_excel('D://learn//毕业设计//BM25-master//poet_url1211_02.xlsx') # 读取URL列表的文件路径
driver = webdriver.Chrome()
try:
crawl_info(url_list, driver) # 将driver传递给crawl_info函数
finally:
driver.quit() # 确保在函数执行结束或发生异常时关闭driver
从Excel中读取URL列表
- 创建一个空列表 url_list,这个列表将用来存放从 Excel 文档中读取的 URL。
- 函数继续通过 for 循环遍历 Excel 工作表中的每一行。sheet.iter_rows(min_row=2, values_only=True) 这段代码指定了遍历的起始行是第二行(min_row=2),因为通常第一行是标题行,不包含实际数据。参数 values_only=True 意味着在迭代时仅返回单元格的值。
def read_url_list_from_excel(file_path):
workbook = openpyxl.load_workbook(file_path)
sheet = workbook.active
url_list = []
for row in sheet.iter_rows(min_row=2, values_only=True):
url = row[1]
if url:
url_list.append(url)
return url_list
请求 url,返回数据处理
def crawl_info(url_list, driver):
# 打开excel文件
workbook = openpyxl.load_workbook('D://work//test//in.xlsx')
sheet = workbook.active
sheet['A1'] = '姓名'
sheet['B1'] = '诗歌名称'
sheet['C1'] = '诗歌地址'
sheet['D1'] = '时间'
sheet['E1'] = '内容'
sheet['F1'] = '浏览量'
sheet['G1'] = '点赞量'
sheet['H1'] = '评论量'
# TODO 完善
# DEBUG writed 写入行号有问题
writed = 2
# url_list是诗人作品列表地址集合
for i, url in enumerate(url_list, start=2):
print("-------------------------------------------------------: ", i)
print("当前时间为:", datetime.now().strftime("%Y-%m-%d %H:%M:%S"))
num_poems = 0
try:
# 请求 url
page_content = getHTMLText(url)
# 返回数据处理
info = extract_info(page_content, url)
poem_names = info['poem_names']
num_poems = len(poem_names) # 获取 poem_names 列表长度
urls = info['urls']
num_urls = len(urls)
for j, poem_name in enumerate(poem_names, start=0):
poem_info_content = getHTMLText2(urls[j])
poem_html_info = get_poem_html_info(poem_info_content, url)
sheet.cell(row=writed + j, column=1, value=info['author_name'])
sheet.cell(row=writed + j, column=2, value=poem_name)
sheet.cell(row=writed + j, column=3, value=urls[j])
sheet.cell(row=writed + j, column=4, value=poem_html_info['time'])
sheet.cell(row=writed + j, column=5, value=poem_html_info['content'])
sheet.cell(row=writed + j, column=6, value=poem_html_info['hit_value'])
sheet.cell(row=writed + j, column=7, value=poem_html_info['favor_value_content'])
sheet.cell(row=writed + j, column=8, value=poem_html_info['comment_count'])
except Exception as e:
print(f'在爬取URL:{url}时出现错误:{e}')
writed += num_poems # 递增行索引,跳过已写入的行
workbook.save('poem_5.xlsx')
请求发送相关方法定义
def getHTMLText2(url):
try:
session = requests.Session()
response = session.post('https://www.zgshige.com/zcms/ajax/invoke', data=login_data)
if response.status_code == 200: # 判断登录成功
# 重新加载首页
response = session.get(url)
else:
print("登录失败")
response.encoding = response.apparent_encoding
return response.text # 获取网页的所有信息
except:
return "Error!"