ef get_data(url): resp = requests.get(url) html = resp.text soup = BeautifulSoup(html,'html.parser') tr_list = soup.find_all('tr') dates,conditions,temp = [],[],[] for data in tr_list[1:]: sub_data = data.text.split() dates.append(sub_data[0]) conditions.append(''.join(sub_data[1:3])) temp.append(''.join(sub_data[3:6])) _data = pd.DataFrame() _data['日期'] = dates _data['天气情况'] = conditions _data['气温'] = temp return _data
时间: 2024-01-14 13:05:02 浏览: 132
这是一个Python函数,用于从指定的URL获取网页数据,并解析出其中的天气数据,返回一个Pandas数据框。具体实现过程如下:
1. 使用requests库向指定的URL发送请求,并获取响应数据;
2. 使用BeautifulSoup库解析HTML页面,获取其中的表格数据;
3. 遍历表格中的每一行数据,将日期、天气情况、气温等信息分别添加到对应的列表中;
4. 创建一个空的Pandas数据框,并将日期、天气情况、气温等信息分别作为列添加到数据框中;
5. 返回这个数据框。
需要注意的是,在解析HTML页面时,使用了html.parser解析器,这是Python内置的解析器,用于解析HTML和XML等格式的文本数据。在遍历表格数据时,使用了列表切片技术,从第二行开始遍历,跳过了表格的标题行。
相关问题
``` import requests from bs4 import BeautifulSoup import time def fetch_links(base_url): start_time = time.time() # 存储已经检查过的URL以及它们的状态码 visited_urls = set() link_status_codes = {} def _fetch_and_check(url_to_visit): nonlocal visited_urls try: response = requests.get(url_to_visit) if response.status_code == 200: soup = BeautifulSoup(response.text, 'lxml') for a_tag in soup.select('a[href]'): href = a_tag['href'] full_link = href if base_url in href and full_link not in visited_urls: visited_urls.add(full_link) status_code = check_link_availability(full_link) link_status_codes[full_link] = status_code yield { 'link': full_link, 'status': status_code, 'elapsed_seconds': round(time.time() - start_time, 2), 'total_links_scanned': len(link_status_codes) } except Exception as e: print(f"[ERROR]: {str(e)}") return list(_fetch_and_check(base_url)) def check_link_availability(url_to_test): try: resp = requests.head(url_to_test) return resp.status_code except Exception: return None if __name__ == '__main__': target_site = input("请输入需要扫描的目标网站:") results = fetch_links(target_site) for result_item in results: print(result_item)```这段代码没有输出结果
你提供的Python脚本旨在通过`requests`库和`BeautifulSoup`解析网页内容,并抓取目标站点内部链接及其HTTP状态码信息。然而,它在实际运行过程中未如预期般输出结果的原因可能是多方面的。
### 可能的问题点
1. **函数返回值处理不当**:
`fetch_links()` 函数最终返回的是 `_fetch_and_check(base_url)` 的列表化生成器对象的结果。但是由于`_fetch_and_check()`是一个递归生成器,在第一次请求后如果不再次触发对新发现链接的进一步访问,则程序不会继续深入爬行其他页面,导致只有一层深度的数据被抓取并立即结束。
2. **缺少递归调用机制**:
当前代码结构里虽然有将新的、未访问过的链接加入到待查集合中的操作(`visited_urls.add(full_link)`),但却缺乏对于新增加进来的这些链接再次发起 HTTP 请求的操作逻辑。也就是说,尽管发现了更多同域下的 URL 地址却没有安排后续动作去验证其有效性等重要步骤。
3. **错误处理不够完善**:
如果遇到网络异常等情况时会直接抛出异常并且打印错误消息,这可能会阻止某些关键部分正常工作而没有给出足够的调试线索给开发者知晓问题所在;另外一些边界情况也可能影响整体流程顺利完成。
4. **输入合法性校验缺失**:
用户从命令行接收的目标网址未经严格的格式检查便投入到了实际使用的环节当中,可能导致不符合规范的字符串混入其中干扰了正常的解析过程。
5. **依赖项安装与否确认不足**:
确认环境中是否正确地安装了所需的第三方包 (`requests`, `beautifulsoup4`) 并配置好 Python 解释器环境也至关重要。
为了修正这些问题,可以参考下面改进后的版本:
```python
import requests
from bs4 import BeautifulSoup
import re
import time
def is_valid_http_url(url):
regex = re.compile(
r'^(?:http|ftp)s?://' # http:// or https://
r'(?:(?:[A-Z0-9](?:[A-Z0-9-]{0,61}[A-Z0-9])?\.)+(?:[A-Z]{2,6}\.?|[A-Z0-9-]{2,}\.?)|'
r'\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})' # ...or ip
r'(?::\d+)?' # optional port
r'(?:/?|[/?]\S+)$', re.IGNORECASE)
return url is not None and bool(regex.match(url))
def fetch_all_links(base_url, max_depth=1):
start_time = time.time()
visited_urls = set()
link_status_codes = []
def recursive_fetch(current_url, depth):
nonlocal visited_urls, link_status_codes
if current_url in visited_urls or depth > max_depth:
return
try:
response = requests.get(current_url, timeout=5)
print(f"Visiting {current_url}... Status Code={response.status_code}")
if response.status_code == 200:
soup = BeautifulSoup(response.content.decode('utf8'), 'html.parser')
for a_tag in soup.find_all('a', href=True):
next_href = a_tag['href']
if is_valid_http_url(next_href): # Ensure it's an absolute path
if base_url in next_href and next_href not in visited_urls:
elapsed_seconds = round(time.time() - start_time, 2)
link_data = {
'link': next_href,
'status': check_link_availability(next_href),
'elapsed_seconds': elapsed_seconds,
'total_links_scanned': len(visited_urls)+1
}
visited_urls.add(next_href)
link_status_codes.append(link_data)
# Recursively visit newly found links within the same domain up to specified maximum depth.
if link_data['status'] == 200 and depth < max_depth:
recursive_fetch(next_href, depth + 1)
except Exception as e:
print(f"[ERROR while processing '{current_url}']: {e}")
pass
recursive_fetch(base_url, 0)
return link_status_codes
def check_link_availability(url_to_test):
try:
resp = requests.head(url_to_test, allow_redirects=True, timeout=5)
return resp.status_code
except Exception:
return "Unreachable"
if __name__ == '__main__':
target_site = input("请输入需要扫描的目标网站 (完整URL地址,例如: https://example.com):\n")
if not is_valid_http_url(target_site.strip()):
raise ValueError("无效的URL格式,请确保包含协议头(如https://)。")
results = fetch_all_links(target_site)
for idx, item in enumerate(results, start=1):
print(f"{idx}. Link:{item['link']} | Status:{item['status']} "
f"| Time Elapsed(s):{item['elapsed_seconds']} | Total Scans Done:{item['total_links_scanned']}"
)
```
这里做了几个重要的调整:
- 添加了一个简单的正则表达式用于初步筛选有效性的URL;
- 修改了主功能函数`fetch_all_links()`接受最大递归层级作为参数控制爬虫深度;
- 引入递归的方式遍历由当前页面指向的所有符合条件的新连接;
- 对于每次成功获取的内容进行了及时的日志记录便于观察进度及排查故障;
- 改进了针对单条链路检测的部分以更贴近真实场景的行为模式比如允许重定向跟读超时设置等等;
- 加强了用户交互界面友好程度保证传入数据的质量从而提高整个系统的稳定性与可靠性。
此外还请注意遵守各网站Robots.txt规则和服务条款以免造成不必要的麻烦。
import requests from bs4 import BeautifulSoup import jieba.analyse import jieba.posseg as pseg from snownlp import SnowNLP import matplotlib.pyplot as plt # 设置请求头,模拟浏览器访问 headers = { 'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3'} # 获取网页内容 def get_html(url): resp = requests.get(url, headers=headers) resp.encoding = resp.apparent_encoding html = resp.text return html # 获取新闻列表 def get_news_list(url): html = get_html(url) soup = BeautifulSoup(html, 'html.parser') news_list = soup.find_all('a', class_="news_title") return news_list # 对文本进行情感分析 def sentiment_analysis(text): s = SnowNLP(text) return s.sentiments # 对文本进行关键词提取 def keyword_extraction(text): keywords = jieba.analyse.extract_tags(text, topK=10, withWeight=True, allowPOS=('n', 'vn', 'v')) return keywords # 对新闻进行分析 def analyze_news(url): news_list = get_news_list(url) senti_scores = [] # 情感分数列表 keyword_dict = {} # 关键词词频字典 for news in news_list: title = news.get_text().strip() link = news['href'] content = get_html(link) soup = BeautifulSoup(content, 'html.parser') text = soup.find('div', class_='article').get_text().strip() # 计算情感分数 senti_score = sentiment_analysis(text) senti_scores.append(senti_score) # 提取关键词 keywords = keyword_extraction(text) for keyword in keywords: if keyword[0] in keyword_dict: keyword_dict[keyword[0]] += keyword[1] else: keyword_dict[keyword[0]] = keyword[1] # 绘制情感分数直方图 plt.hist(senti_scores, bins=10, color='skyblue') plt.xlabel('Sentiment Score') plt.ylabel('Number of News') plt.title('Sentiment Analysis') plt.show() # 输出关键词词频排名 keyword_list = sorted(keyword_dict.items(), key=lambda x: x[1], reverse=True) print('Top 10 keywords:') for i in range(10): print('{}. {} - {:.2f}'.format(i+1, keyword_list[i][0], keyword_list[i][1])) if __name__ == '__main__': url = 'https://www.sina.com.cn/' analyze_news(url)
这是一段Python代码,用于对新闻进行情感分析和关键词提取。它使用了requests库来获取网页内容,使用BeautifulSoup库来解析HTML文档,使用jieba库来进行中文分词和关键词提取,使用SnowNLP库来进行情感分析,使用matplotlib库来绘制情感分数直方图。在主函数中,它调用了get_news_list()函数来获取新闻列表,然后对每篇新闻进行情感分析和关键词提取,并将情感分数和关键词词频存储到列表和字典中。最后,它绘制情感分数直方图,输出关键词词频排名。
阅读全文
相关推荐
















