天天看点

爬虫学习—疫情篇

一、理论

 1、爬虫的分类:

    通用爬虫:搜索引擎的爬虫

    聚焦爬虫:针对特定网站的爬虫

可以看出来了,我们一般用的都是聚焦爬虫吧

 2、聚焦爬虫的工作流程:

    (1)明确URL(请求地址,明确爬什么)

    (2)发送请求,获取响应数据

    (3)保存相应数据,提取有用信息

    (4)处理数据(存储、使用)

 3、双向爬取。

首先我们来熟悉两个基础技术名词:横向爬取 和纵向爬取。。

    横向爬取:所谓横向爬取,是指在爬取的网站页面中,以“页”为单位,找寻该网站分页器规律。一页一页的爬取网

站数据信息,大多数网站,采用分页管理模式,针对这类网站,首先要确立横向爬取方法。。

    纵向爬取:纵向爬取,是指在一个页面内,按不同的“条目”为单位。找寻各条目之间的规律。一条一条的爬取一个

网页中的数据信息。也就是同时爬取一个页面内不同类别数据。

二、

爬虫由:

(1)发送请求,获取响应——requests

(2)解析数据——beautifulsoup、re

(3)保存数据——json

<一>、requests(发送请求,获取响应)

requests是一个简单的pythonHTTP请求库,requests的作用是发送请求获取相应数据

##1.导入模块

import requests

##2.发送请求,获取响应

response=requests.get('https://www.baidu.com/')

##3.获取响应数据

#print(response.encoding)#ISO-8859-1

response.encoding='utf8'

#print(response.text)

print(response.content.decode(encoding='utf8'))

Response.encoding -编码格式

Response.encoding-指定编码格式

Response.text-按照指定编码格式解码输出

可以把前两个合并成一句Response.content.decode(encoding='gbk')。有的网页不是utf-8,可以指定格式用来解码,例gbk

response(响应)常见属性:

    response.text:响应体str类型

    response.econding:二进制转换字符使用的编码

    response.content:响应体bytes类型

<二>、BeautifulSoup

BeautifulSoup是一个可以从HTML或XML文件中提取数据的python库

<1>、安装BeautifulSoup(用Spyder应该是不用安装的)

pip install bs4

pip install lxml

<2>、BeautifulSoup对象:代表要解析整个文档树,它支持遍历文档树和搜索文档树中描述的大部分的方法

<3>创建BeautifulSoup对象

#1、导入模块

from bs4 import BeautifulSoup

#2、创建BeautifulSoup对象

soup=BeautifulSoup("<html>data</html>

#3、创建BeautifulSoup对象

    soup=BeautifulSoup(html_doc,'lxml')

    #4、查找文档中的title标签

    title=soup.find('title')

    #5、查找文档中a(需要的)标签

    a=soup.find('a')

    print(a)#只输出第一个a标签

    a_s=soup.find_all('a')

    print(a_s)#输出所有的a标签

2、根据属性查找

    #方法一、通过命名参数进行指定的

    a=soup.find(id='link1')

    #方法二、使用attrs来指定属性字典,进行查找

    a=soup.find(attrs={'id':'link1'}) (方法二适用性更强)

3、根据文本查找

    text=soup.find(text='陈雨菲')

<5>、BeautifulSoup对象的find方法—Tag对象

Tag对象对应于原始文档中的XML或HTML标签, Tag 对象Tag有很多方法和属性,可用遍历文档树和搜索文档树以及获取标签内容

Tag对象常用属性

    name:获取标签名称

    attrs:获取标签所有属性的键和值

    text:获取标签的文本字符串

#获取a标签的Tag对象

a=soup.find('a')

print(a)

#Tag的name属性,获取标签名

print('标签名',a.name)

#Tag的attrs属性,标签所有属性的键和值

print('所有属性',a.attrs)

#Tag的text属性,获取标签的文本字符串

print('标签文本',a.text)

三、正则表达式

1、概念:正则表达式是一种字符串匹配的模式(pattern)

2、作用:从某个字符串中提取符合某种条件的子串

3、语法

    1..匹配除换行符(\n)以外的所有字符

    2.\d匹配[0-9]的数字

    3.\w匹配字母数字_和中文;

    4*前面的一个匹配模式出现0次或多次

    5+前面的一个匹配模式出现1次或多次

    6?前面的一个匹配模型出现0或1次

 import re

rs=re.findall("a\nc", "a\nc")

print(rs)#['a\nc']

rs=re.findall("a\\\\nc", "a\\nc")

print(rs)#['a\\nc']

rs=re.findall(r"a\nc", "a\nc")

print(rs)#['a\nc']

 正则中使用r原始字符串,能够忽略转义符号带来的影响

带匹配的字符串中有多少个\,r原串正则中就添加多少个\即可

 4、提取json字符串http://ncov.dxy.cn/ncovh5/view/pneumonia

 import requests

from bs4 import BeautifulSoup

import re

#1发送请求,获取响应

response=requests.get('http://ncov.dxy.cn/ncovh5/view/pneumonia')

#2从响应中获取数据

page=response.content.decode()

#3构建BeautifulSoup对象

soup=BeautifulSoup(page,'lxml')

#print(soup)

#4根据id查找,包含全国疫情信息的标签

#st=soup.find(id='getAreaStat')

st=soup.find(id='getListByCountryTypeService2true')

#print(st)

#5获取标签中文本内容

te=st.string#st.text不行

print(te)

#6提取json字符串

json_str=re.findall(r'(

.∗

.∗

)', te)

print(json_str)

5、总结

(1)正则表达式是一种字符串匹配的模式(pattern),在爬虫中主要用于从某个字符串中

提取符合某种条件的子串

(2)常见语法:.[] \d\w*+?

(3)refindall()查找字符串所有与正则匹配的子串返回一个列表,如果没有找到返回空列

(4)refindall()如果正则中没有分组,返回与整个正则匹配的子串,如果正则中有分组,只返

回与分组匹配的子串,分组两边的正则是用于定位的.

(5)正则中使用r原串就是为了消除转移符(\)的影响,也就是匹配的字符串中,有多少个转

移符,r原串的正则中写几个\就可以了.

6、JSON转Python(json.loads())

###JSON转Python

import json

#1、json字符串,转换Python类型数据

#1.1准备json字符串

str='{"provinceName":"台湾","provinceShortName":"台湾","currentConfirmedCount":"2029"}'

#1.2把json字符串转换为python类型的数据

python1=json.loads(str)

#1.3输出结果

print(python1)

#2、json格式文件 转换python类型数据

#2.1打开文件对象

with open('data11.json',encoding='utf-8') as f:

    #2.2把文件中的json格式内容转换python类型数据

    python2=json.load(f)

    #2.3输出

    print(python2)

    print(type(python2))

 7、Python转Json(json.dumps())

##python转换为json

#1python类型数据转换为json字符串json.dumps(obj)

import json

str='{"provinceName":"台湾","provinceShortName":"台湾","currentConfirmedCount":"2029"}'

json1=json.dumps(str)

print(json1)#"{\"provinceName\":\"\u53f0\u6e7e\",\"provinceShortName\":\"\u53f0\u6e7e\",\"currentConfirmedCount\":\"2029\"}"

json2=json.dumps(str,ensure_ascii=False)

print(json2)#"{\"provinceName\":\"台湾\",\"provinceShortName\":\"台湾\",\"currentConfirmedCount\":\"2029\"}"

#2Python类型数据以json格式写入文件json.dump(obj,fp)

with open('data11.json',mode='w') as f:

    python1=json.loads(str)

    #以json格式写入文件,写入的内容不包含非ASCII字符

    a=json.dump(python1,f)

    print(a)

    #以json格式写入文件,写入的内容包含非ASCII字符

    b=json.dump(python1,f,ensure_ascii=False)

    print(b)

四、案例——统计今日(2021/8/3)以来的所有疫情信息

###########案例、统计2021/8/4以来各国的疫情信息###########

import requests

from bs4 import BeautifulSoup

import re

import json

from tqdm import tqdm#进度条

class CoronaVirusSpider(object):

    #类CoronaVirusSpider

    def __init__(self):

        self.home_url='http://ncov.dxy.cn/ncovh5/view/pneumonia'

    def get_content_from_url(self,url):

        #发送请求,获取响应

        response=requests.get(url)

        #从响应中获取数据

        return response.content.decode()

    def parse_home_page(self,home_page):

        #解析首页内容,获取解析后的python数据

        #构建BeautifulSoup对象

        soup=BeautifulSoup(home_page,'lxml')

        #根据id查找,包含全国疫情信息的标签

        script=soup.find(id='getListByCountryTypeService2true')

        #获取标签中文本内容

        text=script.string

        #提取json字符串

        json_str=re.findall(r'(\[.+\])',text)[0]

        #把json转换为python

        data=json.loads(json_str)

        return data

    def save(self,data,path):

        #保存数据

        with open(path,'w',encoding='utf-8') as fp:

            json.dump(data,fp,ensure_ascii=False)

    def crawl_last_day_corona_virus(self):

        #爬取采集最近一天的各国疫情信息

        #1、发送请求,获取首页内容

        home_page=self.get_content_from_url(self.home_url)

        #2、解析首页内容,获取最近一天的各国疫情数据

        last_day_corona_virus=self.parse_home_page(home_page)

        #3、保存数据

        self.save(last_day_corona_virus,'last_day_corona_virus.json')

    def crawl_corona_virus(self):

        #采集各国疫情数据

        #1、加载疫情数据

        with open('last_day_corona_virus.json',encoding='utf-8') as fp:

            last_day_corona_virus=json.load(fp)

        #print(last_day_corona_virus)#得到列表数据

        corona_virus=[]#定义列表,用于存储各国从1、23以来的疫情数据

        #2、遍历各国疫情数据,获取统计的URL

        for country in tqdm(last_day_corona_virus,'采集1.23以来的各国疫情信息'):

        #for country in last_day_corona_virus:

            #3、发送请求,获取json数据

            statistics_data_url=country['statisticsData']

            statistics_data_json_str=self.get_content_from_url(statistics_data_url)

            #4、把json数据转换为python类型的数据,添加到列表中

            statistics_data=json.loads(statistics_data_json_str)['data']

            #print(statistics_data)

            for one_day in statistics_data:

                one_day['provinceName']=country['provinceName']

            #print(statistics_data)

            corona_virus.extend(statistics_data)#放到列表

            #5、把列表以json格式保存为文件

        self.save(corona_virus,'corcona_virus.json')

    def run(self):

        #self.crawl_last_day_corona_virus()#开始运行这个生成last_day_corona_virus.json

        self.crawl_corona_virus()

if __name__=='__main__':

    spider=CoronaVirusSpider()

    spider.run()