最近两天看黑马课程学习了一下爬虫,总结一下吧
黑马课程 一、理论 ?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>")
print(soup)
?出现警告:GuessedAtParserWarning: No parser was explicitly specified 解决警告问题,创建BeautifulSoup对象时,指定解析器 soup=BeautifulSoup("<html>data</html>
<4>、BeautifulSoup对象的find方法 1、根据标签名查找
#1、导入模块
from bs4 import BeautifulSoup
#2、准备文本字符串
html_doc="""<html><head>........ <p class="img_title">陈雨菲羽毛球女单夺冠</p>
"""
#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()
|