学习视频:网易云 Python网络爬虫实战
环境:python3.5,requests,bs4,json,pandas,re,datetime
主要完成内容:爬取了新浪新闻-国内新闻版块的新闻信息,包括新闻标题,正文,编辑,发布时间和来源,并保存到excel中。使用Chrome的检查功能定位相关内容的位置。
需要用到的模块,这个相当于是初级教程,对每个模块的简单应用,具体细致的使用方法还需要再练习。
import requests
from bs4 import BeautifulSoup
from datetime import datetime
import json
import re
http://news.sina.com.cn/china/
先从一篇文章来分析:
def getCommentCounts(newsurl):
m =re.search('doc-i(.*).shtml',newsurl)
newsid=m.group(1)
comments = requests.get(commentURL.format(newsid))
jd = json.loads(comments.text)
return jd['result']['count']['total']
def getNewsDetail(newsurl):
result = {}
res = requests.get(newsurl)
res.encoding = 'utf-8'
soup = BeautifulSoup(res.text,'html.parser')
result['title'] = soup.select(".main-title")[0].text
result['newssource'] = soup.select(".source")[0].text
timesource = soup.select(".date")[0].text
result['dt'] = datetime.strptime(timesource,'%Y年%m月%d日 %H:%M')
result['article'] =''.join([p.text.strip() for p in soup.select("#article p")[:-1]])
result['editor']=soup.select(".show_author")[0].text.strip('责任编辑:')
result['comments'] = getCommentCounts(newsurl)
return result
这里需要对html结构的了解,以及对BeautifulSoup使用select方法的学习。
select方法可以通过标签名,类名,id名,组合,属性等方式进行查找。
从上面的检查中可以看出,标题对应的内容包含在 class=“mian-title”中。因此,select中类名前面加点。同样的,对发布时间和来源也是在类中。
时间获取到的是文本格式的,可以利用datetime模块对时间格式进行转换。
正文内容在 id=“article”下面,并且有多个段落。这里通过组合查找的方式,返回了全部符合的内容。
在文本处理中,strip()还是非常好用的,strip()用来移除字符串头尾指定的字符(默认为空格或换行)。lstrip(),rstrip()分别是对
获取文章评论总数
评论数不能直接从网页抓取,是从JavaScript链接上来的。
这一段的链接为:
http://comment5.news.sina.com.cn/page/info?version=1&format=json&channel=gn&newsid=comos-hawmaua4736155&group=undefined&compress=0&ie=utf-8&oe=utf-8&page=1&page_size=3&t_size=3&h_size=3&thread=1
标红部分对应了文章的编号。因此尝试获取这段内容,并且在移除多余字符以后,把json格式转换成字典格式。
{'article': '原标题:暴雨蓝色预警:重庆贵州等7省份部分地区有大雨或暴雨中国天气网讯 中央气象台5月22日06时继续发布暴雨蓝色预警:预计,22日08时至23日08时,重庆中南部、贵州东部、云南北部和东部、广西西部、湖南东北部、江西北部、浙中部等地的部分地区有大雨或暴雨,其中,重庆南部、贵州北部局地有大暴雨(100~140毫米);上述部分地区有短时强降水(20~40毫米,局地60毫米以上),局地有雷暴大风或冰雹等强对流天气。防御指南:1、建议政府及相关部门按照职责做好防御暴雨应急工作;2、切断有危险地带的室外电源,暂停户外作业;3、做好城市排涝,注意防范可能引发的山洪、滑坡、泥石流等灾害。',
'comments': 0,
'dt': datetime.datetime(2018, 5, 22, 6, 46),
'editor': '余鹏飞 ',
'newssource': '中国天气网',
'title': '暴雨蓝色预警:重庆等7省份部分地区有大雨或暴雨'}
爬取当前页的所有文章链接
利用Chrome检查中的network监听,在国内新闻主页滚动的时候,页面存在非同步的载入。
http://api.roll.news.sina.com.cn/zt_list?channel=news&cat_1=gnxw&cat_2==gdxw1||=gatxw||=zs-pl||=mtjj&level==1||=2&show_ext=1&show_all=1&show_num=22&tag=1&format=json&page=6&callback=newsloadercallback&_=1526954543004
通过preview的内容,可以发现这个内容包含了一个页面的所有文章信息。
res = requests.get('http://api.roll.news.sina.com.cn/zt_list?channel=news&cat_1=gnxw&cat_2==gdxw1||=gatxw||=zs-pl||=mtjj&level==1||=2&show_ext=1&show_all=1&show_num=22&tag=1&format=json&page=8&callback=newsloadercallback&_=1526880797249')
jd = json.loads(res.text.lstrip(' newsloadercallback(').rstrip(');'))
for ent in jd['result']['data']:
print(ent['url'])
因此,根据一页产生的连接,我们可以把当前页的内容全部保存下来。
def parseListLinks(url):
newsdetails = []
res = requests.get(url)
jd = json.loads(res.text.lstrip(' newsloadercallback(').rstrip(');'))
for ent in jd['result']['data']:
newsdetails.append(getNewsDetail(ent['url']))
return newsdetails
建立多页连接
利用Chrome检查中的network监听,在切换页面时候,上面api的关键参数page可以控制。因此可以通过for循环快速产生多个分页清单的连接。用format()实现数据填充。
url = 'http://api.roll.news.sina.com.cn/zt_list?channel=news&cat_1=gnxw&cat_2==gdxw1||=gatxw||=zs-pl||=mtjj&level==1||=2&show_ext=1&show_all=1&show_num=22&tag=1&format=json&page={}&callback=newsloadercallback&_=1526880797249'
for i in range(1,10):
newsurl = url.format(i)
print(newsurl)
最后,根据分页连接,将每个分页的内容全部下载。
url = 'http://api.roll.news.sina.com.cn/zt_list?channel=news&cat_1=gnxw&cat_2==gdxw1||=gatxw||=zs-pl||=mtjj&level==1||=2&show_ext=1&show_all=1&show_num=22&tag=1&format=json&page={}&callback=newsloadercallback&_=1526880797249'
news_total = []
for i in range(1,3):
newsurl = url.format(i)
newsary = parseListLinks(newsurl)
news_total.extend(newsary)
保存到dataframe中。 head()可以查看表格内容。
import pandas as pd
df = pd.DataFrame(news_total)
df.head()
dataframe数据保存到文件中。
df.to_excel('sina_news.xlsx')
总结
一整套内容完成下来花的时间不多,要学会怎么去分析,怎么利用工具去分析。抓取的内容跟视频的讲解的已经有些变化,要自己清楚了解对应的关键位置,关键参数。