【Python网络爬虫】爬取疫情数据和资讯生成网页

✨博文作者 wangzirui32
喜欢的可以 点赞 收藏 关注哦~~
我的第159篇原创作品
本文首发于CSDN,未经许可禁止转载


hello,大家好,我是wangzirui32,今天我们来学习如何爬取疫情数据和资讯生成网页,开始学习吧!

目录

  • 1. 项目结构及准备
  • 2. 爬虫思路
    • 2.1 分析资讯网页
    • 2.2 API接口
  • 3.编写代码
    • 3.1 get_news函数
    • 3.2 get_data函数
    • 3.3 app.py
    • 3.4 news_template.html 模板

1. 项目结构及准备

【Python网络爬虫】爬取疫情数据和资讯生成网页_第1张图片
app.py为主程序,用来生成网页,data.py用来爬取资讯和数据,news_template.html为信息网页的模板,news.html为程序运行之后生成的网页。
需要安装的包(命令):

pip install jinja2 BeautifulSoup4 selenium

注:selenium需要浏览器驱动,可以去对应浏览器的官网下载

2. 爬虫思路

我们需要通过selenium控制浏览器对新浪网的资讯进行抓取,通过访问API接口获取今日信息,然后整合成网页。

2.1 分析资讯网页

这里的资讯来源于新浪网,访问搜索首页,获取Xpath路径:
搜索框的Xpath为:

//*[@id="tabc02"]/form/div/input[1]

搜索按钮的Xpath为:

//*[@id="tabc02"]/form/div/input[4]

接下来,搜索关键字,HTML网页分析如下:
【Python网络爬虫】爬取疫情数据和资讯生成网页_第2张图片
可以看到,所有的新闻都保存在class属性为box-result clearfixdiv标签中,其中的第一个a标签为新闻的链接和标题,下面的span标签保存了作者和发布时间。
下一页按钮的Xpath为:

//*[@id="_function_code_page"]/a[last()]

分析完成后即可编写代码。

2.2 API接口

数据API接口网址:https://c.m.163.com/ug/api/wuhan/app/data/list-total,返回数据示例:
【Python网络爬虫】爬取疫情数据和资讯生成网页_第3张图片
依据需要获取即可。

3.编写代码

3.1 get_news函数

打开data.py,编写get_news函数:

from selenium.webdriver import Edge   # 我使用的是Edge浏览器
from bs4 import BeautifulSoup as bs
import requests

def get_news():
    print("Requesting data ......")
    page = 5  # 5页新闻
    url = "https://search.sina.com.cn/news"
    html = []
    # Edge浏览器驱动位置
    driver = Edge(r"D:\msedgedriver.exe")
    driver.get(url)
    # 输入关键词
    driver.find_element_by_xpath('//*[@id="tabc02"]/form/div/input[1]').send_keys("疫情")
    # 点击搜索按钮
    driver.find_element_by_xpath('//*[@id="tabc02"]/form/div/input[4]').click()

    for _ in range(page):
  		# 获取当前页的源代码
        html.append(driver.page_source)
        # 点击“下一页”
        driver.find_element_by_xpath('//*[@id="_function_code_page"]/a[last()]').click()
    
    driver.close()
    print("Requested successfully.")

    articles = []

    print("Parsing data ......")
	
	# 解析网页
    for h in html:
        soup = bs(h, "html.parser")

        div_list = soup.find_all("div", {"class": "box-result clearfix"})

        for div in div_list:
            title = div.find("h2").text
            link = div.find("a").get("href")

            temp = div.find("span", {"class": "fgray_time"}).text.split()
            author = temp[0]
            create_time = ' '.join(temp[1:])
	
            # 生成字典
            news = {
                "title": title,
                "link": link,
                "author": author,
                "create_time": create_time
            }
			
			# 防止重复
            if not (news in articles): articles.append(news)
        

    print("Parsed successfully.")
    
    return articles

3.2 get_data函数

打开data.py,编写get_data函数用来获取API数据,代码:

def get_data():
    url = "https://c.m.163.com/ug/api/wuhan/app/data/list-total"
    headers = {
        "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/102.0.5005.63 Safari/537.36 Edg/102.0.1245.30"
    }
    data = requests.get(url, headers=headers).json().get("data").get("chinaTotal")

    return data

3.3 app.py

app.py代码如下:

from jinja2 import Template
import datetime
from data import get_data, get_news

def render_template(news, data):
    try:
        with open("news_template.html", encoding="utf-8") as f:
            template = f.read()
    except Exception:
        return
    print("Rendering news template ......")
    news_template = Template(template)
    render_html = news_template.render(news=news, data=data, now_time=datetime.datetime.now().strftime("%Y-%m-%d %H:%M:%S"))
    print("Rendered successfully.")
    return render_html

with open("news.html", "w") as f:
    html = render_template(get_news(), get_data())
    f.write(html)

3.4 news_template.html 模板

打开news_template.html,键入HTML代码:

DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>News - Covid-19title>
    <style>
        body {
            padding-left: 20px;
        }
        .row .col-md-3 {
            text-align: center;
        }
    style>
    <link rel="stylesheet" href="https://stackpath.bootstrapcdn.com/bootstrap/3.4.1/css/bootstrap.min.css" integrity="sha384-HSMxcRTRxnN+Bdg0JdbxYKrThecOKuH5zCYotlSAcp1+c8xmyTe9GYg1l9a69psu" crossorigin="anonymous">
head>
<body>
    <div class="container" id="news">
        <h1>新冠疫情资讯h1>
        <p>共计{{ news | length }}条新闻p>
        <p>更新时间:{{ now_time }}p>
        <div class="panel panel-default">
            <div class="panel panel-footer">
                <div class="row">
                    <div class="col-md-3" style="color:red">
                        <h3>累计确诊h3>
                        <p>{{ data['total']['confirm'] }}p>
                    div>
                    <div class="col-md-3" style="color:black">
                        <h3>累计死亡h3>
                        <p>{{ data['total']['dead'] }}p>
                    div>
                    <div class="col-md-3" style="color:gold">
                        <h3>累计境外输入h3>
                        <p>{{ data['total']['input'] }}p>
                    div>
                    <div class="col-md-3" style="color:cyan">
                        <h3>累计治愈h3>
                        <p>{{ data['total']['heal'] }}p>
                    div>
                    <div class="col-md-3" style="color:gray">
                        <h3>新增死亡h3>
                        <p>{{ data['today']['dead'] }}p>
                    div>
                    <div class="col-md-3" style="color:indianred">
                        <h3>新增病例h3>
                        <p>{{ data['today']['confirm'] }}p>
                    div>
                    <div class="col-md-3" style="color:crimson">
                        <h3>现有确诊h3>
                        <p>{{ data['today']['confirm'] }}p>
                    div>
                    <div class="col-md-3" style="color:brown">
                        <h3>现有无症状h3>
                        <p>{{ data['extData']['noSymptom'] }}p>
                    div>
                div>
            div>
        div>
        <div class="news">
            <ol class="list-group" style="font-size: 17px;">
                {% for i in news %}
                    <li class="list-group-item">
                        <a href="{{i['link']}}" target="_blank">{{i['title']}}a>
                        <small style="color:gray">
                            媒体:{{i['author']}}
                            发布于{{i['create_time']}}
                        small>
                    li>
                {% endfor %}
            ol>
            <p style="color:gray">以上资讯来自新浪官网p>
            <p style="color:gray">疫情数据来自网易官网p>
        div>
body>
html>

运行代码,即可在news.html中查看效果了。


好了,今天的课程就到这里,我是wangzirui32,喜欢的可以点个收藏和关注,我们下次再见!

你可能感兴趣的:(Python网络爬虫,Python,python,爬虫,开发语言)