File "F:\pyproject\demo2.py", line 25, in get_info phone = soup.find('span',class_='index_detail-tel__fgpsE').text ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ AttributeError: 'NoneType' object has no attribute 'text'的问题
时间: 2023-08-05 11:10:51 浏览: 126
这个错误通常表示在使用 .text 属性时,对象为 NoneType,也就是在 BeautifulSoup 中没有找到对应的标签或属性。你需要检查一下代码中的 soup.find() 方法是否正确地定位到了你需要的标签和属性,如果没有找到,可以尝试使用其他方法或检查一下网页结构是否有变化。另外,也可以在使用 .text 属性前,先通过 if 判断一下对象是否存在,避免抛出 AttributeError 异常。
相关问题
import requests from bs4 import BeautifulSoup import openpyxl from time import sleep # 设置请求头,模拟浏览器访问 headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36'} # 从天眼查获取公司邮箱和电话 def get_info(company): email = '' phone = '' url = 'https://www.tianyancha.com/search?key=' + company r = requests.get(url, headers=headers) soup = BeautifulSoup(r.text, 'html.parser') # try: # 获取公司详情页链接 company_url = soup.find_all('a', class_='index_alink__zcia5 link-click')[0].get('href') r = requests.get(company_url, headers=headers) soup = BeautifulSoup(r.text, 'html.parser') # 获取公司邮箱和电话 email = soup.find_all('span', class_='index_detail-email__B_1Tq')[0].text sleep(0.5) phone = soup.find('span',class_='index_detail-tel__fgpsE').text # except: # pass # return email,phone # 从Excel文件中读取公司名称 def read_from_excel(file_path): wb = openpyxl.load_workbook(file_path) ws = wb.active company_list = [] for row in ws.iter_rows(min_row=2, values_only=True): company_list.append(row[0]) return company_list # 将公司邮箱和电话写入Excel文件 def write_to_excel(company_list): wb = openpyxl.Workbook() ws = wb.active ws.title = 'Company Info' # 写入表头 ws.cell(row=1, column=1, value='Company Name') ws.cell(row=1, column=2, value='Email') ws.cell(row=1, column=3, value='Phone') # 写入数据 for i, company in enumerate(company_list): email,phone = get_info(company) ws.cell(row=i+2, column=1, value=company) ws.cell(row=i+2, column=2, value=email) ws.cell(row=i+2, column=3, value=phone) # 保存Excel文件 wb.save('company_info.xlsx') if __name__ == '__main__': file_path = 'company_names.xlsx' company_list = read_from_excel(file_path) write_to_excel(company_list)优化这段代码
这段代码可以进行以下优化:
1. 在函数 get_info 中,使用 try...except 捕获异常会使代码难以维护。可以使用 if...else 判断 soup.find_all() 和 soup.find() 是否返回了有效结果,如果无效则将 email 和 phone 赋值为空字符串。
2. 在函数 write_to_excel 中,每次调用 get_info() 都会发起一个 http 请求,这会导致程序运行速度变慢。可以先将所有公司的详情页链接获取到,再一次性请求,减少 http 请求的次数。
下面是优化后的代码:
```
import requests
from bs4 import BeautifulSoup
import openpyxl
from time import sleep
# 设置请求头,模拟浏览器访问
headers = {
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/114.0.0.0 Safari/537.36'
}
# 从天眼查获取公司邮箱和电话
def get_info(company, company_urls):
email = ''
phone = ''
url = 'https://www.tianyancha.com/search?key=' + company
r = requests.get(url, headers=headers)
soup = BeautifulSoup(r.text, 'html.parser')
# 获取公司详情页链接
company_url = soup.find_all('a', class_='index_alink__zcia5 link-click')
if company_url:
company_urls.append(company_url[0].get('href'))
# 获取公司邮箱和电话
if company_urls:
r = requests.get(company_urls[-1], headers=headers)
soup = BeautifulSoup(r.text, 'html.parser')
email = soup.find('span', class_='index_detail-email__B_1Tq')
phone = soup.find('span', class_='index_detail-tel__fgpsE')
if email:
email = email.text
if phone:
phone = phone.text
sleep(0.5)
return email, phone
# 从Excel文件中读取公司名称
def read_from_excel(file_path):
wb = openpyxl.load_workbook(file_path)
ws = wb.active
company_list = []
for row in ws.iter_rows(min_row=2, values_only=True):
company_list.append(row[0])
return company_list
# 将公司邮箱和电话写入Excel文件
def write_to_excel(company_list):
company_urls = []
for company in company_list:
email, phone = get_info(company, company_urls)
company_urls.pop()
row_num = len(company_urls) + 2
ws.cell(row=row_num, column=1, value=company)
ws.cell(row=row_num, column=2, value=email)
ws.cell(row=row_num, column=3, value=phone)
# 保存Excel文件
wb.save('company_info.xlsx')
if __name__ == '__main__':
file_path = 'company_names.xlsx'
company_list = read_from_excel(file_path)
wb = openpyxl.Workbook()
ws = wb.active
ws.title = 'Company Info'
# 写入表头
ws.cell(row=1, column=1, value='Company Name')
ws.cell(row=1, column=2, value='Email')
ws.cell(row=1, column=3, value='Phone')
write_to_excel(company_list)
```
import os import csv from bs4 import BeautifulSoup # 设置文件夹路径 folder_path = 'C:/Users/test/Desktop/DIDItest' # 遍历文件夹中的所有文件和子文件夹 for root, dirs, files in os.walk(folder_path): for file_name in files: if file_name.endswith('.html'): file_path = os.path.join(root, file_name) # 打开HTML文件并读取源代码 with open(file_path, 'r', encoding='utf-8') as file: html_content = file.read() # 在这里可以对源代码进行进一步的操作和提取 soup = BeautifulSoup(html_content, 'html.parser') messages = soup.find_all('p') for message in messages: talk_id_tag = message.find_previous('a') if talk_id_tag: talk_id = talk_id_tag.text.strip()[1:] time = message.contents[0].strip().split(',')[0][1:] send_phone = message.find('span', class_='hint-success').text.strip() receive_phone = message.find_all('span', class_='hint-success')[1].text.strip() content_tag = message.find('a') if content_tag: content = content_tag['href'] content_type = '音频' else: content = message.text.strip() content_type = '文本' print("talkid:", talk_id) print("时间:", time) print("发送号码:", send_phone) print("接收号码:", receive_phone) print("发送内容:", content) print()将提取到的数据写入csv中
要将提取到的数据写入CSV文件,你可以使用Python的CSV模块。首先,你需要在循环之前创建一个CSV文件并写入表头。然后,在每次迭代时,将提取到的数据写入CSV文件的相应行。
以下是修改后的代码示例:
```python
import os
import csv
from bs4 import BeautifulSoup
# 设置文件夹路径
folder_path = 'C:/Users/test/Desktop/DIDItest'
# 创建CSV文件并写入表头
csv_file_path = 'output.csv'
with open(csv_file_path, 'w', newline='', encoding='utf-8') as csv_file:
writer = csv.writer(csv_file)
writer.writerow(['talkid', '时间', '发送号码', '接收号码', '发送内容'])
# 遍历文件夹中的所有文件和子文件夹
for root, dirs, files in os.walk(folder_path):
for file_name in files:
if file_name.endswith('.html'):
file_path = os.path.join(root, file_name)
# 打开HTML文件并读取源代码
with open(file_path, 'r', encoding='utf-8') as file:
html_content = file.read()
# 在这里可以对源代码进行进一步的操作和提取
soup = BeautifulSoup(html_content, 'html.parser')
messages = soup.find_all('p')
for message in messages:
talk_id_tag = message.find_previous('a')
if talk_id_tag:
talk_id = talk_id_tag.text.strip()[1:]
time = message.contents[0].strip().split(',')[0][1:]
send_phone = message.find('span', class_='hint-success').text.strip()
receive_phone = message.find_all('span', class_='hint-success')[1].text.strip()
content_tag = message.find('a')
if content_tag:
content = content_tag['href']
content_type = '音频'
else:
content = message.text.strip()
content_type = '文本'
# 将提取到的数据写入CSV文件
writer.writerow([talk_id, time, send_phone, receive_phone, content])
# 打印完成的提示信息
print("数据已成功写入CSV文件。")
```
在这个示例中,我们首先创建了一个CSV文件,使用 `csv.writer` 来写入表头。然后,在每次迭代时,使用 `writer.writerow` 将提取到的数据写入CSV文件的相应行。最后,打印出提示信息表示数据已成功写入CSV文件。
请注意,你需要根据实际情况修改CSV文件的路径和表头内容。
阅读全文