赞
踩
最近一直在学习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()
如果运行这段代码控制台出现html代码就代表第一步成功了
(若html中这里出现中文乱码,请尝试使用下面的方法)
response = requests.get(url).encoding('utf8')
或者
response.encoding = 'utf8'
若不知道html的编码,可以用
print(response.apparent_encoding)
这样打印出来的就是你的网页的编码方式
第三步:解析索引页
导入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)
运行结果
当然在这里也可以将结果用字典输出
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)
结果是这样
当然还需要找出每一页的url,我们点击下一页,查看每一页的url有什么规律,是直接修改的url还是修改的参数
很明显,总页数283,往下一页的话,url就每次-1,所以我们要在这也要顺便获取一下总页数
#获取总页数
page_pattern = re.compile(' 1/(.*?) ')
pagenum = re.findall(page_pattern,content)
pagenum1 = int(pagenum[0])#将str的页数转成int类型,后面循环要用到
print(pagenum1)
当然,把这个获取页数的代码放到下面获取所有url的函数中可能更好
第四步:获取全部需要抓取的url
定义一个函数
def parse_all_url(content):
#解析索引页面上的总页数
page_pattern = re.compile(' 1/(.*?) ')
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)#解析索引页的相关内容
第五步:抓取并解析详细页信息
构造抓取详细页函数,这个和抓取索引页的函数几乎一样
#构造抓取详细页函数
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
构造解析详细页函数,由于详细页的正文内容中有很多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()
这样运行出来的话,结果在下方
我们可以看到,在content里面有很多\n(换行符),与\xa0(不间断空格符),我们需要将这些换行符等符号去除掉
results = soup.find('div',class_='imggin').get_text().strip().replace('\n','').replace('\xa0','')
运行结果如下,成功将换行符等去除
未写完,待续,先把暂时的代码放在下方(可以直接运行)
# -*- 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(' 1/(.*?) ')
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()
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。