更新博客:
前言
之前使用腾讯新闻提供的接口爬取数据,详见之前的博文:
然而腾讯新闻提供的接口太烦人了,老是换,而且从那里爬下来的数据老是不更新。当时也很疑惑,明明页面显示的是实时更新的数据,但接口的lastUpdate
一直是False
。
一开始一直在找腾讯新闻实时页面的接口,但发现用requests
爬下来的压根没有相关的数据。又去看了丁香园的页面,看起来比腾讯的好爬一些,因此转战丁香园(这个感觉是因为当时一直用的requests
,没去细看网页源码。后来腾讯实时页面用的selenium
,再到写博客的时候发现丁香园如果requests
解析的时候不给出页面内容的话,也可以用selenium
,这个等写腾讯页面的爬取时再说吧)。
当然这也只是暂时。因为很快我们就发现,丁香园的数据出现一些错误(也可能刚好就是那几天老出错而已)。于是耐着性子去捣鼓腾讯新闻的实时数据。最后的最后,丁香园跟腾讯的都爬下来啦。
先写下怎么爬丁香园实时页面的数据,后面再写怎么爬腾讯新闻实时页面的数据。这是个比较啰嗦的记录…
其实就是一边看爬下来的内容,一边找要的内容…另外,爬下来的数据处理部分并不是很好,一方面是因为之前那个服务器不能用pandas
,不方便用DataFrame
对象,所以数据处理部分自行改善。
丁香园实时界面
首先,先前往丁香园的网页。因为主要是想要海外数据,这里我们选择板块:
点进去会进入以下页面:
requests探索
我们先使用requests
解析后看看页面内容是什么:
import json
import requests
from bs4 import BeautifulSoup
from datetime import datetime
url = 'https://ncov.dxy.cn/ncovh5/view/pneumonia_top?from=dxy&source=&link=&share='
reponse = requests.get(url)
r = reponse.text
这里有很多东西,仔细看可以发现有时间戳、需要的数据,还有一些乱码的部分,这些我们要的内容就放在<script id="getListByCountryTypeService2true"></script>
里面。
BeautifulSoup解析
我们用BeautifulSoup来解析内容
soup = BeautifulSoup(reponse.text,'html.parser')
data = soup.find(name = 'script', attrs = {'id': 'getListByCountryTypeService2true'})
data = data.string
这里再看下data
,可以发现我们爬下来了整个列表数据,我们所需要的部分放在一个[]
里,下面就用正则匹配来匹配要的部分内容:
# 匹配数据
pattern1 = r'\[(.*?)]'
data = re.findall(pattern1, str(data))
data = data[0]
这时候我们要的那部分内容就放到一个字符串变量里,里面是很多个{}
。每个{}
放着一条数据,我们再用正则匹配把这些数据匹配出来:
pattern2 = r'({.*?})'
resultDict = re.findall(pattern2, data)
这会爬下来的就是一个列表,每个元素就是一条数据:
我们拿出其中一个元素来进行探索:
temp = resultDict[0]
temp = json.loads(temp + '}')
首先里面有时间戳(这里是13位数的),需要转换为常见的时间格式,还有乱码的问题。我们提取部分需要(按自己需求提取)的内容进行处理:
temp = resultDict[0]
temp = json.loads(temp + '}')
tempNeed = {}
if len(str(temp['createTime'])) > 10:
tempTime = float(temp['createTime']/1000)
tempTime = datetime.fromtimestamp(int(tempTime))
tempTime = tempTime.strftime("%Y/%m/%d %H:%M:%S")
tempNeed['time'] = tempTime
tempNeed['place'] = temp['provinceName'].encode('iso-8859-1').decode('utf8')
tempNeed['country_en'] = temp['countryFullName']
tempNeed['up_place'] = temp['continents'].encode('iso-8859-1').decode('utf8')
tempNeed['confirmed_num'] = temp['confirmedCount']
tempNeed['die_num'] = temp['deadCount']
tempNeed['cure_num'] = temp['curedCount']
我们看下处理后的样子:
这里为什么要加}
呢?也是尝试的时候报 错 发现的,前面正则匹配下来的的玩意里有一些内部还有{}
,这里面放了当日新增数据,但不是所有的元素都有这个(后面读取的时候会用一个try
来处理):
提取需要部分
到这里就差不多了,提取我们要的部分,自行决定要怎么使用这些内容。
另外注意一点,在处理时发现部分数据是没有createTime
或者modifyTime
的,由于爬取的时间戳基本一致,我们直接拿第一个时间作为爬取时间就好。
outList = []
for i in range(len(resultDict)):
try:
resultDict[i] = json.loads(resultDict[i] + '}')
except:
resultDict[i] = json.loads(resultDict[i])
place_dict = {}
place_dict['time'] = tempTime
place_dict['place'] = resultDict[i]['provinceName'].encode('iso-8859-1').decode('utf8')
place_dict['country_en'] = resultDict[i]['countryFullName']
place_dict['up_place'] = resultDict[i]['continents'].encode('iso-8859-1').decode('utf8')
place_dict['confirmed_num'] = resultDict[i]['confirmedCount']
place_dict['die_num'] = resultDict[i]['deadCount']
place_dict['cure_num'] = resultDict[i]['curedCount']
outList.append([place_dict['time'], place_dict['place'],
place_dict['country_en'], place_dict['up_place'],
place_dict['confirmed_num'], place_dict['die_num'],
place_dict['cure_num']])
结语
以上就是利用requests
跟BeautifulSoup
爬取丁香园页面的主要内容啦,爬下来之后再自行利用数据进行分析吧!
下一篇再写使用selenium
爬取腾讯新闻的实时页面。