python爬虫学习之旅(四)

爬取一点点语录网


运行环境:Python3
编译软件:Sublime


这次来爬取这个一点点语录网
 
先来看看这是一个怎样的网页
 

一点点语录网
 
在这里插入图片描述
 
工作内容

爬取标题和相应内容,并保存在本地
 
同样的第一步,确定爬取目标,搞清url
 

第一页:http://www.yikexun.cn/lizhi/qianming/list_50_1.html
第二页:http://www.yikexun.cn/lizhi/qianming/list_50_2.html
第三页:http://www.yikexun.cn/lizhi/qianming/list_50_3.html

可以清晰地看出,每一页的url构成都很简单,有明显的数字标识可以确定这是第几页。
并且url中的list_50明显的说明了该页有50条内容
设置默认url为

 url = 'http://www.yikexun.cn/lizhi/qianming/list_50_'

 
相比之前爬取贴吧,这个在url设置上更简单,只需要给定起始页和结束页就可以进行爬取
 
设置请求头

将url的拼接以及发送请求设置为一个函数,方便后面的调用。
此后的爬虫程序都会以此来进行
 
handle_request(发送响应获得请求) 函数代码:

def handle_request(url,page=None):
    if page !=None:
        url = url +str(page) +'.html'
    headers = {
   'User-Agent':'Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0;',
    }
    request = urllib.request.Request(url=url,headers=headers)
    return request

这里在返回 request 后,需要读取里面的数据
 

content = urllib.request.urlopen(request).read().decode()

 
这里由于原页面返回的是bytes类型,需要decode()解码,转换成str类型。
 

检查网页元素,通过正则匹配待爬取的数据地址
 

对原网页检查元素
 

在这里插入图片描述
 
确定标题是在网页的这一层
会发现其他标题地址都是类似如此
所以就用正则匹配的方法来进行
 

        pattern = re.compile(r'<h3><a href="(/lizhi/qianming/\d+\.html)">(.*?)</a></h3>')
        lt = pattern.findall(content)

 
就是要匹配出所有如下的地址
 

<a href="/lizhi/qianming/20181241081.html">比你优秀的人还在努力——激励自己,不放弃的经典语录</a>

 
匹配结果如下图所示
 
正则匹配结果
返回的lt是一个列表,列表中的元素都是元组,元组中第一个元素就是正则中第一个小括号匹配到的内容,元组中第二个元素就是正则中第二个小括号匹配的内容
 

遍历得到的 lt,以此得到标题和相对应内容
 

返回的 lt 如上所说是一个列表,其中有两个元素,一个是链接,另一个是标题内容

('/lizhi/qianming/20181140997.html', '<b>人到死都要怀抱梦想!</b>')

而需要把其中的标题提取出来

title = href_title[-1]

上面这条代码,将 href_title 中的倒数第一个放进 title,也就是第二个元素(文字部分)
 

        for href_title in lt:
            a_href = 'http://www.yikexun.cn' +href_title[0]
            title = href_title[-1]
            text = get_text(a_href)
            string = '<h1>%s</h1>%s' % (title,text)

 
但是这里是得到了标题,并没有返回其具体内容,
所以写了 get_text 来获得标题下的具体内容

通过之前设置好的 handle_request 函数来发送请求获得响应,就不做过多赘述
从之前的标题点进去,检查元素,确定内容的具体地址
在这里插入图片描述
同样,通过正则来对内容的路径进行匹配,在这里用了 re.S模式进行匹配
re.S(DOTALL): 点任意匹配模式,改变’.'的行为
不然程序会报错
在这里插入图片描述

特别在这里注意的是,爬取内容的时候,网页中可能会有些许图片,在这里用正则将这些图片内容去除掉,得到的是纯文本信息

    pat  = re.compile(r'<img .*?>')
    text = pat.sub(' ',text)

通过上面者两行代码,将所有图片地址转换为空地址,以做到将图片内容去除
 
get_text 函数代码:

def get_text(a_href):
    #调用函数构建请求对象
    request = handle_request(a_href)
    #发送请求,得到响应
    content = urllib.request.urlopen(request).read().decode()
    #解析内容  注意路径,最好从原网页中复制!!!
    pattern = re.compile(r'<div class="neirong">(.*?)</div>',re.S)
    lt = pattern.findall(content)
    text = lt[0]
    #将图片信息清空
    # 注意路径,最好从原网页中复制!!!
    pat  = re.compile(r'<img .*?>')
    text = pat.sub(' ',text)
    return text

最后就是将爬取到的内容写进本地html文件
得到的结果就是下图所示
在这里插入图片描述
注意事项:
也是我自己犯的错误,在写正则的时候,对于原网页检索元素得到的地址最好从原网页复制,一些很小的符号或者空格之类,都会影响正则的识别,包括之后的xpath也是一样!

最后附上程序所有代码

import urllib.request
import urllib.parse
import re

def handle_request(url,page=None):
    if page !=None:
        url = url +str(page) +'.html'
    headers = {
   'User-Agent':'Mozilla/5.0 (compatible; MSIE 9.0; Windows NT 6.1; Trident/5.0;',
    }
    request = urllib.request.Request(url=url,headers=headers)
    return request

def get_text(a_href):
    #调用函数构建请求对象
    request = handle_request(a_href)
    #发送请求,得到响应
    content = urllib.request.urlopen(request).read().decode()
    #解析内容  注意路径,最好从原网页中复制!!!
    pattern = re.compile(r'<div class="neirong">(.*?)</div>',re.S)
    # pattern = re.compile(r'<div class="neirong">(.*?)</div>')
    lt = pattern.findall(content)
    text = lt[0]
    # print(text)
    # exit()
    #将图片信息清空
    # 注意路径,最好从原网页中复制!!!
    pat  = re.compile(r'<img .*?>')
    text = pat.sub(' ',text)
    return text

def parse_content(content):
    #正则
        pattern = re.compile(r'<h3><a href="(/lizhi/qianming/\d+\.html)">(.*?)</a></h3>')
        lt = pattern.findall(content)
        # 标题终端输出
        # print(lt)
        # exit()
        #返回的lt是一个列表,列表中的元素都是元组,元组中第一个元素就是正则中第一个小括号匹配到的内容,元组中第二个元素就是正则中第二个小括号匹配的内容
        for href_title in lt:
            a_href = 'http://www.yikexun.cn' +href_title[0]
            title = href_title[-1]
            text = get_text(a_href)
            string = '<h1>%s</h1>%s' % (title,text)
            with open('lizhi.html', 'a',encoding = "utf-8") as fp:
                fp.write("<meta charset='utf-8'>")
                fp.write(string)

def main():
    url = 'http://www.yikexun.cn/lizhi/qianming/list_50_'
    start_page = int(input('请输入起始页:'))
    end_page = int(input('请输入结束页:'))
    for page in range(start_page,end_page +1):
        #根据url组合和page生成指定request
        request = handle_request(url,page)
        content = urllib.request.urlopen(request).read().decode()
        parse_content(content)

if __name__ == '__main__':
    main()



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值