python3 re如何用来提取大量的数据

278次阅读
没有评论

python3

我们想要查看一个网页上所有的数据内容,应该如何做呢?相信小伙伴们知道该怎么做。那如果小编在限制一下条件,用到python爬虫和re模块的知识,不知道还有没有人能回答上来这个问题?本篇的内容相较于之前只有纯代码模块,但是代码的内容较多,也算是给小伙伴们一次新的突破和挑战,具体代码一起看看吧。

re_label_script
作者: Klaus_Lyu
# -*- coding:utf-8 -*-
# 自定义创建文件夹并保存图片
import re
import os
from urllib.request import urlretrieve
 
content = '''
<script>var images = [
{ "big":"http://i-2.yxdown.com/2015/3/18/KDkwMHgp/6381ccc0-ed65-4422-8671-b3158d6ad23e.jpg";;,
  "thumb":"http://i-2.yxdown.com/2015/3/18/KHgxMjAp/6381ccc0-ed65-4422-8671-b3158d6ad23e.jpg";;,
  "original":"http://i-2.yxdown.com/2015/3/18/6381ccc0-ed65-4422-8671-b3158d6ad23e.jpg";;,
  "title":"","descript":"","id":75109},
{ "big":"http://i-2.yxdown.com/2015/3/18/KDkwMHgp/fec26de9-8727-424a-b272-f2827669a320.jpg";;,
  "thumb":"http://i-2.yxdown.com/2015/3/18/KHgxMjAp/fec26de9-8727-424a-b272-f2827669a320.jpg";;,
  "original":"http://i-2.yxdown.com/2015/3/18/fec26de9-8727-424a-b272-f2827669a320.jpg";;,
  "title":"","descript":"","id":75110},
</script>
'''
 
# 自定义函数,在创建新的文件夹
# 固定,可直接套用
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
def mkdir(path):
    # 去除首位空格
    path = path.strip()
    # 去除尾部符号 ‘\\’
    path = path.rstrip("\\")
    # 判断路径是否存在
    isExists = os.path.exists(path)
    # 去掉目录路径,返回文件夹名
    fp_new = os.path.basename(path)
    if not isExists:
        # 如果不存在,则创建目录 os.makedirs(path)
        os.makedirs(path)
        print(path + '  新文件夹' + fp_new + '创建成功')
        return True
    else:
        # 如果目录存在则不创建
        print(path + '  文件夹' + fp_new + '已存在')
        return False
 
# 当前路径下创建文件夹用来保存图片
# 获取当前路径dir_path
dir_path = os.path.abspath(".")
# dir_new 绝对路径
dir_new = dir_path + '\\pic_down'           # 新建文件夹的名字
# 传参并创建新文件夹在当前路径下,文件夹名称为pic_down
mkdir(dir_new)
# 固定,可直接套用
# ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
 
html_script = r'<script>(.*?)</script>'
info_script = re.findall(html_script, content, re.S|re.M)
for script in info_script:
    res_original = r'"original":"(.*?)"'  # 原图
    pic_script = re.findall(res_original, script)
    for pic in pic_script:
        print(pic)
        # urlretrieve()函数下载图片
        filename = os.path.basename(pic)                    # 去掉目录路径,返回文件名
        urlretrieve(pic, dir_new + '\\' +filename)        #下载图片
 
 
 
re_label_span 过滤<span></span>等标签
作者: Klaus_Lyu
# -*- coding:utf-8 -*-
# 过滤<span></span>等标签
import re
 
language = '''
<table class="infobox bordered vcard" style="width: 21em; font-size: 89%; text-align: left;" cellpadding="3">
<caption style="text-align: center; font-size: larger;"><b>周恩来</b></caption>
<tr>
<th>性別:</th>
<td>男</td>d
</tr>
<tr>
<th>異名:</th>
<td><span>(字) 翔宇</span></td>
</tr>
<tr>
<th>政黨:</th>
<td><span><a href="../articles/%E4%B8%AD9A.html" title="中国共产党">中国共产党</a></span></td>
</tr>
<tr>
<th>籍貫:</th>
<td><a href="../articles/%E6%B5%9981.html" title="浙江省">浙江省</a><a href="../articles/%E7%BB%8D82.html" title="绍兴市">绍兴市</a></td>
</tr>
</table>
'''
 
# 获取table中的tr值
res_tr = r"<tr>(.*?)</tr>"
info_tr = re.findall(res_tr, language, re.S|re.M)
for line in info_tr:
    # 获取表格第一列 th 属性
    res_th = r"<th>(.*?)</th>"
    info_th = re.findall(res_th, line, re.S|re.M)
    # print(info_th)          # ['性別:']\n['異名:']\n['政黨:']\n['籍貫:']
    for mm in info_th:
        # 处理掉href链接
        if "href" in mm:    # 如果href链接存在info_th中,则处理
            restr = r'<a href=.*?>(.*?)</a>'  # 只获取a标签的内容,不获取链接 re.findall() (.*?)
            h = re.findall(restr, mm, re.S|re.M)
            print(h[0])    # 为什么加逗号
        else:
            print(mm)      # 为什么加逗号
 
    # 获取表格第二列 th 属性
    res_td = r'<td>(.*?)</td>'
    info_td = re.findall(res_td, line, re.S|re.M)
    for nn in info_td:            # 两个if判断的先后顺序
        # 处理掉href链接或者rel等信息 (对于政党中既有span 又有a标签,由于内容是在a标签中,不须考虑span的影响)
        if "href" in nn:        # 判断内容直接所属的标签
            res_value = r'<a .*?>(.*?)</a>'     # 处理<a href=../rel=..></a>等信息
            td_value = re.findall(res_value, nn, re.S|re.M)
            # print(td_value)
            for value in td_value:              # 一个td中可能会有多个href或者rel等信息
                print(value)
        elif "span" in nn:
            res_value = r'<span .*?>(.*?)</span>'     # 对于政党中,由于已经先判断了href,故不会执行到elif span中
            td_value = re.findall(res_value, nn, re.S|re.M)
            for value in td_value:
                print(value)
        else:
            print(nn)
 
 
 
 
 
re_label_sub img_replace br (过滤掉换行符)
作者: Klaus_Lyu
# -*- coding:utf-8 -*-
# 获取<img ../>中超链接及过滤<img>标签
import os
import re
 
value = '''
<table style="width: 21em; text-align: left;" cellpadding="3">
<tr bgcolor="#CDDBE8">
<th colspan="2">
<center><b>中華民國政治人士</b><br /></center>
</th>
</tr>
<tr>
<th>性別:</th>
<td>男</td>
</tr>
<tr>
<th>政黨:</th>
<td><span>
<img alt="中國國民黨" src="../../../../images/Kuomintang.svg.png" width="19" height="19" border="0" />
<a href="../../../../articles/%8B%E6%B0%91%E9%BB%A8.html" title="中國國民黨">中國國民黨</a></span></td>
</tr>
</table>
'''
# # 过滤HTML标签 ,<>包含的内容全部替换为空值
# value = re.sub('<[^>]+>', '', value) # 过滤HTML标签 ,<>包含的内容全部替换为空值
# print(value)
 
# 先过滤掉上诉替换空值后的换行符</br>
if '</br>' in value or '\n' in value:
    value = value.replace('</br>', '') # </br>替换为空值
    value = value.replace('\n', ' ') # \n替换为空格
 
value = re.sub('<[^>]+>', '', value) # <>包含的内容全部替换为空值, 首位有空格
# 中華民國政治人士 性別: 男 政黨: 中國國民黨
value = value.strip() # 去掉value首尾的空格
# 中華民國政治人士 性別: 男 政黨: 中國國民黨
print(value)
 
 
 
 
re_label_table
作者: Klaus_Lyu
# -*- coding:utf-8 -*-
import re
 
s = '''<table>
<tr>
<td>序列号</td><td>DEIN3-39CD3-2093J3</td>
<td>日期</td><td>2013年1月22日</td>
<td>售价</td><td>392.70 元</td>
<td>说明</td><td>仅限5用户使用</td>
</tr>
</table>
'''
info = re.findall(r"<td>(.*?)</td><td>(.*?)</td>", s, re.S|re.M)
for line in info:
    print(line[0],line[1])        #或者print(line) 一样的结果
# 序列号 DEIN3-39CD3-2093J3
# 日期 2013年1月22日
# 售价 392.70 元
# 说明 仅限5用户使用
 
#     print(line[1])
# DEIN3-39CD3-2093J3
# 2013年1月22日
# 392.70 元
# 仅限5用户使用
 
 
 
re_label_title
作者: Klaus_Lyu
# -*- coding:utf-8 -*-
import re
from urllib.request import urlopen
 
request = urlopen("http://www.csdn.net/";).read().decode('utf-8';)
 
print("方法一:")           # re.search()   撇配第一个
title_pat = r"<a.*?title=.*?(?=target=)"
title_obj = re.search(title_pat, request, re.I|re.M)
title = title_obj.group()
print(title)             # re.search() 只匹配满足条件的第一条记录
# <a title="理解情感 — 从Keras移植到pyTorch" href="http://geek.csdn.net/news/detail/239227";;
 
 
print("方法二:")
title_obj = re.findall(r"(?<=<a )title=.*?(?=target=)", request, re.I|re.M)
print(title_obj[0])
# title="理解情感 — 从Keras移植到pyTorch" href="http://geek.csdn.net/news/detail/239227";;
 
 
 
re_label_tr(td/th)
作者: Klaus_Lyu
# -*- coding:utf-8 -*-
import re
 
language = '''<tr><th>性別:</th><td>男</td></tr><tr><th>性別:</th><td>女</td></tr>'''
# 正则表达式获取<tr></tr>之间内容
# 核心代码:
res_tr = r'<tr>(.*?)</tr>'
m_tr = re.findall(res_tr, language, re.S|re.M)
# /核心代码
 
for line in m_tr:
    print(line)
 
# 获取表格第一列th属性
res_th = r'<th>(.*?)</th>'
m_th = re.findall(res_th, line, re.S|re.M)
for mm in m_th:
    print(mm)
 
# 获取表格第二列td属性
res_td = r'<td>(.*?)</td>'
m_td = re.findall(res_td, line, re.S|re.M)
for nn in m_td:
    print(nn)
# results:
# < th > 性別: < / th > < td > 男 < / td >
# 性別:
# 男
# < th > 性別: < / th > < td > 女 < / td >
# 性別:
# 女
 
 
 
 
 
 
re_label_head
作者: Klaus_Lyu
# -*- coding:utf-8 -*-
import re
 
content = """<head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    <title>
豆瓣电影 Top 250
</title>
    <meta http-equiv="Expires" content="Sun, 6 Mar 2005 01:00:00 GMT">
    <link rel="apple-touch-icon" href="https://img3.doubanio.com/f/movie/d59b2715fdea4968a450ee5f6c95c7d7a2030065/pics/movie/apple-touch-icon.png">;;
    <script type="text/javascript">var _head_start = new Date();</script>
<link href="https://img3.doubanio.com/f/movie/dcfd6c93a0b44f2495c6ab3cdf21d8508b97bb03/css/movie/top_movies.css";; rel="stylesheet" type="text/css" />
    <style type="text/css">img { max-width: 100%; }</style>
    <script type="text/javascript"></script>
    <link rel="shortcut icon" href="https://img3.doubanio.com/favicon.ico";; type="image/x-icon">
</head>"""
 
# 核心代码:
# regex = r'<meta http-equiv=.*?>'
# regex = r'(?<=<meta )http-equiv=.*?(?=>)'
 
 
# regex = r'(?<=link.*?)href=".*?(?=")|(?<=link.*?)href=\'.*?(?=\')'
# 前提条件(?<=link.*?)不对,必须是确定的,不能用匹配的表达式,正确的是(?<=link )
link_href = re.findall(r'(?<=<link ).*?href="(.*?)(?=")', content, re.M|re.S)   # refindall()只匹配括号里的(.*?)
for line in link_href:
    print(line)
    # https://img3.doubanio.com/f/movie/d59b2715fdea4968a450ee5f6c95c7d7a2030065/pics/movie/apple-touch-icon.png
    # https://img3.doubanio.com/f/movie/dcfd6c93a0b44f2495c6ab3cdf21d8508b97bb03/css/movie/top_movies.css
    # https://img3.doubanio.com/favicon.ico
 
link_metal = re.findall(r'(?<=<meta )http-equiv=.*?(?=>)', content,)
for line in link_metal:
    print(line)
    # http - equiv = "Content-Type" content = "text/html; charset=utf-8"
    # http - equiv = "Expires"  content = "Sun, 6 Mar 2005 01:00:00 GMT"
 
link_metal = re.findall(r'<meta http-equiv=.*?>', content,)
for line in link_metal:
    print(line)
    # <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
    # <meta http-equiv="Expires" content="Sun, 6 Mar 2005 01:00:00 GMT">
 
 
 
re_label_href
作者: Klaus_Lyu
# -*- coding:utf-8 -*-
import re
from urllib.request import urlopen
 
# !!!!!爬取豆瓣top250首页的源代码
# 自定义函数获取网页源代码,自动获取网站编码格式并按相应格式解码赋值给request
def download(html):
    urlorgs = urlopen(html).read()
    # 检测url的编码格式
    # char_url = chardet.detect(urlorgs)
    # print(char_url['encoding'])
    # print(char_url)    # {'encoding': 'GB2312', 'confidence': 0.99, 'language': 'Chinese'}
                         # url按照对应的编码格式进行解码输出, chardet.detect()内容为key-value字典
    # request = urlorgs.decode(char_url['encoding'])
    request = urlorgs.decode('utf-8')
    return request
 
# 传参 html,获得正确编码后的网页源代码
request = download("https://movie.douban.com/top250";;)
# print(request)
 
# 爬链接要有针对性地根据目标值来观察链接的特征,依据特征进行针对性地爬取
# # 爬取a标签中所有URL链接 (目测意义不大)
urls = re.findall(r"<a.*?href=.*?</a>", request, re.I|re.M)
for url in urls:
    print(url)
 
# 爬取所有href前缀的link(目测也是意义不大)
link_list = re.findall(r"(?<=href=\").+?(?=\")|(?<=href=\').+?(?=\')", request)
for url in link_list:
    print(url)

通过上述代码我们能得知,python的re模块在获取大量数据方面同样可以起到作用,只是代码过于复杂,所以不太适合新手小白的学习。小伙伴们也可以复制代码体验一下,向进阶突破的感觉。

神龙|纯净稳定代理IP免费测试>>>>>>>>天启|企业级代理IP免费测试>>>>>>>>IPIPGO|全球住宅代理IP免费测试

相关文章:

版权声明:wuyou2021-05-25发表,共计9927字。
新手QQ群:570568346,欢迎进群讨论 Python51学习