当前位置:   article > 正文

带你写爬虫(python)第一篇----抓取安徽理工大学新闻网中所有新闻_爬取安徽大学新闻资讯前三页python代码

爬取安徽大学新闻资讯前三页python代码

最近一直在学习python爬虫,所以一直想写个简单的爬虫教程,所以第一篇就拿母校新闻网官网来练手了,没想到写爬虫的过程还停一波三折的。(后来发现新闻网页面还有访问限制,多次访问后,本机ip就被限制了,本文不讨论这个)

准备工作
- 目标页面:http://news.aust.edu.cn
- 开发工具:pycharm
- python版本:3.6.4
- 所需库:请求库requests,解析库re,BeautifulSoup
- 这里不介绍各种库安装和使用方法,推荐查看
- BS模块:Python爬虫利器二之Beautiful Soup的用法
- re模块: Python爬虫入门七之正则表达式

爬取过程分析
第一步:获取每一个索引页面的url
第二步:解析每一个索引页面,获取每个文章标题和详细页的url等信息
第三步:爬取并解析详情页的相关信息

第一步:分析页面
分析所需爬取页面,浏览器打开页面,主要抓取的就是图片中框住的部分,本文主要介绍第一个“学校要闻”(第二个“综合要闻”类比,该文不赘述)
这里写图片描述

点击“学校要闻”,进入单独的页面:http://news.aust.edu.cn/xxxw.htm,之后按F12进行页面分析
这里写图片描述
查看之后,发现这个这些数据都直接在html里面,不是用ajax加载的,那就比较简单的了。

第二步:爬取索引页
打开pycharm,新建一个工程,在工程里面新建一个文件spider.py
这里写图片描述
定义第一个函数,抓取索引页的html代码,导入requests模块以及对应的异常处理模块,这里使用requests模块进行抓取,未使用urllib库

import requests
from requests.exceptions import RequestException

#抓取索引页面
def get_index_html():
    #目标网页
    url = 'http://news.aust.edu.cn/xxxw.htm'
    try:
        #使用requests的get方法获取url的html全部代码
        response = requests.get(url)
        if response.status_code ==200:
            return response.text
        return None
    except RequestException:
        return None
#主函数
def mian():
    get_index_html()

if __name__ == '__main__':
    main()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

如果运行这段代码控制台出现html代码就代表第一步成功了
(若html中这里出现中文乱码,请尝试使用下面的方法)

response = requests.get(url).encoding('utf8')
或者
response.encoding = 'utf8'
  • 1
  • 2
  • 3

若不知道html的编码,可以用

print(response.apparent_encoding)
  • 1

这样打印出来的就是你的网页的编码方式

第三步:解析索引页
导入re模块,定义一个解析函数,这里使用re模块正则表达式进行匹配解析(当然这里也可以用xpath,BeaytifulSoup等方式,请自行选择)

#导入re模块,用于正则匹配使用
import re
#定义解析索引页函数
def parse_index_html(content):
    #构造正则表达式,使用re.S模式来匹配换行
    pattern = re.compile('<font>(.*?)</font>.*?absmiddle.*?href="(.*?)" target="_blank">(.*?)</a>',re.S)
    #使用findall方法获取所有结果,结果为一个list格式
    results = re.findall(pattern,content)
    print(results)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

运行结果
这里写图片描述
当然在这里也可以将结果用字典输出

rooturl = 'http://news.aust.edu.cn/'#详细页url的最前面的根url(html中写的是相对地址)
for result in results:
        data = {
            'time':result[0],
            'url':rooturl+result[1],#合并成每一页的url
            'content':result[2]
        }
        print(data)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

结果是这样
这里写图片描述
当然还需要找出每一页的url,我们点击下一页,查看每一页的url有什么规律,是直接修改的url还是修改的参数
这里写图片描述
这里写图片描述
很明显,总页数283,往下一页的话,url就每次-1,所以我们要在这也要顺便获取一下总页数

#获取总页数
    page_pattern = re.compile('&nbsp;1/(.*?)&nbsp')
    pagenum = re.findall(page_pattern,content)
    pagenum1 = int(pagenum[0])#将str的页数转成int类型,后面循环要用到
    print(pagenum1)
  • 1
  • 2
  • 3
  • 4
  • 5

当然,把这个获取页数的代码放到下面获取所有url的函数中可能更好

第四步:获取全部需要抓取的url
定义一个函数

def parse_all_url(content):
    #解析索引页面上的总页数
    page_pattern = re.compile('&nbsp;1/(.*?)&nbsp')
    pagenum = re.findall(page_pattern, content)
    pagenum1 = int(pagenum[0])
    #获取每一页的url
    rooturl = 'http://news.aust.edu.cn/xxxw/'
    #循环构造所有详细页的url
    for page in range(0,pagenum1):
        if page ==0:
            wholeurl = 'http://news.aust.edu.cn/xxxw.htm'
        else :
            wholeurl = rooturl+str(pagenum1-page)+'.htm'
        # print(wholeurl)
        content = get_index_html(wholeurl)#获取索引页的html代码
        result = parse_index_html(content)#解析索引页的相关内容
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

第五步:抓取并解析详细页信息
构造抓取详细页函数,这个和抓取索引页的函数几乎一样

#构造抓取详细页函数
def get_detail_html():
    try:
        response = requests.get(url)
        if response.status_code == 200:
            # print(response.apparent_encoding)
            response.encoding = 'utf8'
            return response.text
        return None
    except RequestException:
        return None
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

构造解析详细页函数,由于详细页的正文内容中有很多html标签,所以使用正则匹配比较复杂,这里使用BeautifulSoup相对而言更加适用。当然要先导入BeautifulSoup模块

from bs4 import BeautfulSoup
#构造解析详细页函数
def parse_detail_html(url):
    content = get_detail_html(url)
    if content:
        #构造bs对象,使用lxml解析方法,更加快速
        soup = BeautifulSoup(content,'lxml')
        results = soup.find('div',class_='imggin').get_text().strip()   
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

这样运行出来的话,结果在下方
这里写图片描述
我们可以看到,在content里面有很多\n(换行符),与\xa0(不间断空格符),我们需要将这些换行符等符号去除掉

results = soup.find('div',class_='imggin').get_text().strip().replace('\n','').replace('\xa0','')
  • 1

运行结果如下,成功将换行符等去除
这里写图片描述
未写完,待续,先把暂时的代码放在下方(可以直接运行)

# -*- coding: utf-8 -*-
# @Time    : 2018/2/5 14:06
# @Author  : XueLei
# @Site    : 
# @File    : spider.py
# @Software: PyCharm
import re
import requests
from bs4 import BeautifulSoup
from requests.exceptions import RequestException

#获取索引页,需要加一个timeout
def get_index_html(url):
    try:
        response = requests.get(url,timeout = 200)#我在这加了一个超时参数
        if response.status_code == 200:
            response.encoding = 'uft8'
            return response.text
        return None
    except RequestException as e:
        print(e)
        return None

#解析索引页,获取各文章的标题
def parse_index_html(content):
    #首页
    rooturl = 'http://news.aust.edu.cn/'
    # 匹配模式,S模式
    pattern = re.compile('<li id=.*?<font>(.*?)</font>.*?absmiddle.*?href="(.*?)" target="_blank">(.*?)</a>',re.S)
    results = re.findall(pattern,content)
    #遍历结果输出
    for result in results:
        publish_time = result[0]
        detail_url = rooturl+result[1]
        str1 = '../'#用于去除字符串中的../字符
        if detail_url:
            if str1 in detail_url:#如果字符串中有../
                detail_url = detail_url.replace('../','')
            paracontent = parse_detail_html(detail_url)#抓取并解析详细页信息
        title = result[2]
        data = {
            'time':publish_time,
            'url':detail_url,
            'title':title,
            'content':paracontent
        }
        print(data)

#获取详细页
def get_detail_html(url):
    try:
        response = requests.get(url)
        if response.status_code == 200:
            # print(response.apparent_encoding)
            response.encoding = 'utf8'
            return response.text
        return None
    except RequestException as e:
        return e
#解析详细页,这里使用BeautiulSoup进行解析
def parse_detail_html(url):
    content = get_detail_html(url)
    if content:
        soup = BeautifulSoup(content,'lxml')
        results = soup.find('div',class_ = 'imggin').get_text().strip().replace('\n','').replace('\xa0','')
        return results
    return None


#去除图片
def remove_all_img():
    return None
#去除标签
def remove_all_label():
    return None
#获取每一页的url
def parse_all_url(content):
    #解析索引页面上的总页数
    page_pattern = re.compile('&nbsp;1/(.*?)&nbsp')
    pagenum = re.findall(page_pattern, content)
    page1 = int(pagenum[0])
    #获取每一页的url
    rooturl = 'http://news.aust.edu.cn/xxxw/'
    #循环构造url,并调用索引页解析函数
    for page in range(0,page1):
        if page ==0:
            wholeurl = 'http://news.aust.edu.cn/xxxw.htm'
        else :
            wholeurl = rooturl+str(page1-page)+'.htm'
        print(wholeurl,'这是第'+str(page+1)+"页")
        content = get_index_html(wholeurl)#获取每一各索引页的代码,用于找到url和标题
        parse_index_html(content)#解析每一索引页的代码


def main():
    url = 'http://news.aust.edu.cn/xxxw.htm'#首页面
    print(url)
    html = get_index_html(url)#这个只是解析总页数
    # print(html)
    try:
        parse_all_url(html)#获取总页数,并构造每一页的url
    except RequestException as e:
        print(e)


if __name__ == '__main__':
    main()
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72
  • 73
  • 74
  • 75
  • 76
  • 77
  • 78
  • 79
  • 80
  • 81
  • 82
  • 83
  • 84
  • 85
  • 86
  • 87
  • 88
  • 89
  • 90
  • 91
  • 92
  • 93
  • 94
  • 95
  • 96
  • 97
  • 98
  • 99
  • 100
  • 101
  • 102
  • 103
  • 104
  • 105
  • 106
  • 107
  • 108
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小桥流水78/article/detail/958705
推荐阅读
相关标签
  

闽ICP备14008679号