爬虫基础实战 二(封装抓取网页代码)

上节回顾

上节主要学习了:

  1. requests get 网页
  2. 使用bs4中的BeautifulSoup格式化网页
  3. 通过select进行标签查找
  4. text文本显示内容
  5. 格式化时间

封装待处理网页

import requests
from bs4 import BeautifulSoup
httplink = 'http://news.sina.com.cn/c/nd/2016-08-20/doc-ifxvctcc8121090.shtml'
res = requests.get(httplink)
res.encoding = 'utf-8'
soup = BeautifulSoup(res.text,'html.parser')

提取网页内容

通过审查元素,查找原文可以知道,文章内容在“id=artibody”下,所以

soup.select('#artibody')

爬虫基础实战 二(封装抓取网页代码)_第1张图片

因为我们需要的事“p”标签里面的内容所以

soup.select('#artibody p')

同时因为也不要最后一段所以

soup.select('#artibody p')[:-1]

爬虫基础实战 二(封装抓取网页代码)_第2张图片

从上面我们已经得到了文章内容,但是被“p”标签隔开,所以我们需要却掉标签连接起来

爬虫基础实战 二(封装抓取网页代码)_第3张图片

最后得到是一个列表,显然不是我们要的,所以通过

' '.join(artlist)

连接起来,获得需要的字符串

一行文写上面的代码

artlist = [i.text.strip() for i in soup.select('#artibody p')[:-1]]
' '.join(artlist)

一样的效果但是更简洁。
来更简洁一些

artstr = ' '.join([i.text.strip() for i in soup.select('#artibody p')[:-1]])

取得编辑名称

editor = soup.select('.article-editor')[0].text.strip('责任编辑:')

取得评论数

爬虫基础实战 二(封装抓取网页代码)_第4张图片

爬虫基础实战 二(封装抓取网页代码)_第5张图片

从上图发现,查找到的评论数,居然过滤出来的是空列表。
所以推测,这数值来源于js生成。

从新加载开发者工具后,在js中遍历找到了评论的位置。

import requests
comments = requests.get('http://comment5.news.sina.com.cn/page/info?version=1&format=js&channel=gn&newsid=comos-fxvctcc8121090&group=&compress=0&ie=utf-8&oe=utf-8&page=1&page_size=20')

import json
jd = json.loads(comments.text.strip('var data='))

这时候获得json字典,然后在观察网页,会发现评论在 result 下的 count 内total的valun之。

jd['result']['count']['total']

最终取得 评论数。

抓取ID

newaurl = 'news.sina.com.cn/c/nd/2016-08-20/doc-ifxvctcc8121090.shtml'

# url通过“/”分割
newsid = newaurl.split('/')
# 获得列表后我们打开最后一项
newsid = newsid[-1]
# 去掉“.shtml”
newsid = newsid.rstrip('.shtml')
# 最后过滤掉“doc-”
newsid = newsid.lstrip('doc-')
print(newsid)

上面的方法太长了,也可以用正则表达式。

import re
m = re.search('doc-(.*).shtml',newaurl)
print(m.group(1))

封装评论数

import re
import json
import requests

def getCommentCounts(newsurl):
    # 先获取评论的id
    m = re.search('doc-i(.+).shtml',newsurl)
    newsid = m.group(1)
    # 设置样式链接
    commentURL ='http://comment5.news.sina.com.cn/page/info?version=1&format=js&channel=gn&newsid=comos-fxvctcc8121090&group=&compress=0&ie=utf-8&oe=utf-8&page=1&page_size=20'
    # 把id塞入样式链接形成有效连接
    comments = requests.get(commentURL.format(newsid))
    jd =json.loads(comments.text.strip('var date='))
    return jd['result']['count']['total']

完整最终装抓取代码

import requests
from bs4 import  BeautifulSoup
from datetime import datetime
import re
import json

# 封装评论数
# 需要的库 “import re” “import json”
def getCommentCounts(newsurl):
    # 先获取评论的id
    m = re.search('doc-i(.+).shtml',newsurl)
    newsid = m.group(1)
    # 设置样式链接
    commentURL ='http://comment5.news.sina.com.cn/page/info?version=1&format=js&channel=gn&newsid=comos-fxvctcc8121090&group=&compress=0&ie=utf-8&oe=utf-8&page=1&page_size=20'
    # 把id塞入样式链接形成有效连接
    comments = requests.get(commentURL.format(newsid))
    jd =json.loads(comments.text.strip('var date='))
    return jd['result']['count']['total']

def getNewsDetil(newsurl):
    result = {}
    # 封装待处理网页
    # 需要的库 “import requests”“from bs4 import  BeautifulSoup”
    res = requests.get(newsurl)
    res.encoding = 'utf-8'
    soup = BeautifulSoup(res.text,'html.parser')
    # 获取标题
    result['title'] = soup.select('#artibodyTitle')[0].text
    # 新闻来源
    result['newssource'] = soup.select('.time-source span a')[0].text
    # 获取时间
    # 需要的库 “from datetime import datetime”
    result['dt'] = datetime.strptime(soup.select('.time-source')[0].contents[0].strip(),'%Y年%m月%d日%H:%M')
    # 获取内容
    result['article'] = ' '.join([p.text.strip() for p in soup.select('#artibody p')[:-1]])
    # 获取编辑
    result['editor'] = soup.select('.article-editor')[0].text.strip('责任编辑:')
    # 获取评论数
    result['comments'] = getCommentCounts(newsurl)
    return result

你可能感兴趣的:(Python爬虫)