目录名字中包含日期正则匹配_python 爬虫2:解析源代码(正则表达、BeautifulSoup,剑来小说/哪吒电影短评)...

BeautiulSoup学习网址:Beautiful Soup 4.2.0 文档

一、方式一:正则表达式

要掌握正则表达式的常用符号,包括

  • 一般字符

. 匹配任意单个字符

转义字符

[...]字符集

  • 预定义字符集

d 匹配一个数字字符。等价于 [0-9]。

D 匹配一个非数字字符。等价于 [^0-9]。

s 匹配任何空白字符,包括空格、制表符、换页符等等。等价于 [ fnrtv]

S 匹配任何非空白字符。等价于 [^ fnrtv]

w 匹配包括下划线的任何单词字符。等价于'[A-Za-z0-9_]

W 匹配任何非单词字符。等价于 '[^A-Za-z0-9_]

  • 数量词

* 匹配前一个字符0或无限次

+ 匹配前一个字符1或无限次

? 匹配前一个字符0或1次

{m} 匹配前一个字符m次

{m,n} 匹配前一个字符m至n次

  • 边界匹配

^ 匹配字符串开头

$ 匹配字符串结尾

A 仅匹配字符串开头

Z 仅匹配字符串结尾

正则表达式练习1 re.findall

text = '''2月份,各地继续落实地方调控主体责任,坚持因城施策,促进房地产市场平稳健康发展。
据初步测算,4个一线城市新建商品住宅销售价格环比上涨0.3%,涨幅比上月回落0.1个百分点。
其中:北京下降0.2%,上海和广州分别上涨0.3%和1.1%,深圳持平。
二手住宅销售价格环比上涨0.15%。其中:北京和深圳分别上涨0.2%和0.5%,上海和广州分别下降0.1%和0.2%。
31个二线城市新建商品住宅销售价格环比上涨0.7%,涨幅连续三个月相同;
二手住宅销售价格环比下降20.21%,降幅比上月扩大0.1个百分点。
35个三线城市新建商品住宅销售价格环比上涨10.4%,涨幅比上月回落0.2个百分点;
二手住宅销售价格环比上涨0.2%,涨幅与上月相同。'''

# 把上面这段话中的所有百分比数值提取出来

思路: 1. 后面是百分号结尾 2. 百分号前边一定是数字, 数字的位数不确定 ,至少有一个
import re
re.findall( r'd+.?d+%', text)  #方法一
re.findall('d+.d+%' ,  text)   #方法二
re.findall('[d.]*%', text)  #方法三

正则表达式练习2

text1 = """西楼尘 看过  2018-07-02
最费力的成长留在树上的只有壳,最狰狞的伤口留在皮肤的只有疤。
 
7596 有用 凌睿 看过  2018-08-02
或是被第三者插足,或是不受父母待见,或是被辞退,却共同组成了最温馨家庭。 
举报
 
4170 有用 九只苍蝇撞墙 看过  2018-06-11
那些说是枝一直致敬小津的人可以歇歇了。这次他拍了部让小津最深恶痛绝的今村昌平式的蛆虫电影。

举报
 
3627 有用 咯咯精 看过  2018-05-14
如果说爱你,还打你,那一定是说谎;如果爱你,就会像安藤樱一样紧紧抱住你。(沉溺于安藤樱的美色无法自拔

举报
 
3347 有用 姨妈的鸭 看过  2018-06-23
比起放下手机,这本电影在观影时需要观众做的第一步是:放下三观。"""

#提取“有用”前面的数字

re.findall(r"(d+) 有用" , text1)

#提取 数字+“有用”

re.findall(r"d+ 有用" , text1)

#提取日期

re.findall(r"d{4}-d{2}-d{2}",text1)

#把年月日分开

r1 = re.findall(r'(d+)-(d+)-(d+)', text1)

#提取用户名

re.findall(r"(S+) 看过",text1)

正则表达式练习3 提取天猫超市狗粮重量(t.findall、t.extractall

15acd9660c7e5cb33c9ef9b1e1d0c390.png
import pandas as pd
df = pd.read_excel('Product_details_test.xlsx')
t = df.TradeName.str

5cd5bc19ab89405a62011176d56df27f.png
t.findall(r'd+k?g',flags = re.I)  #这时用.findall()提取出来的重量是列表

6c72f051d582f3fd0009b175a80a6c18.png
result_1 = t.extractall(r'(d+k?g)',flags = re.I)  # 自动添加一列索引列

de91058e17d678414c9996ae48ac2a22.png
result = t.extract(r'(d+)(k?g)',flags = re.I)  # 重量和单位分开

fbedb1d675f29fa9b577a0f50a85607d.png
result_2 = t.extract(r'(d+k?g)',flags = re.I)  # 重量和单位在一列

07997400470801397a7c6ca1923a34b8.png

注意:

  • - pandas 中str属性支持正则表达式的方法整理
  • - contains 包含,返回bool类型, 包含规则返回真,否则返回假
  • - extract 按组提取, 必须加括号分组, 提取出匹配出来的第一个数据
  • - extractall 按组提取, 必须加括号分组, 提取出匹配到的所有数据
  • - findall 提取出匹配到的所有数据, 默认返回列表
爬取网络小说的逻辑:
1. 先爬取每一章节的链接
2. 测试其中一章节的爬取
3. 使用循环爬取所有的章节, 分别储存到一个txt文件中
4. 可以再试一下, 把整部小说保存到一个文档中去.

二、案例1:爬取剑来小说 (利用正则表达式解析)

网址:http://www.shuquge.com/txt/8659/index.html

思路:
1. 从目录页里面把所有的章节列表链接提取出来
2. 先随便找一个章小说, 爬取测试
3. 把代码组合成函数, 抓取一章内容的函数命名为get_one_page_content() 编写保存到本地文件的功能.
4. 对chapter_link中的每一个连接进行循环, 调用get_one_page_content()获取到章节的标题和章节的内容
5. 将标题和内容保存下来
6. 对所有的章节遍历保存整部小说

做法:

第1步:定义一个函数,实现功能: 传进去一个链接, 返回的小说标题、内容

def get_one_page_content(url):
    """功能: 传进去一个链接, 返回的就是小说的名称还有小说的内容"""
    import requests 
    import re
    # 添加Hearder
    headers = {'user-agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36'}
    #  先随便找一个章小说, 爬取测试
    r = requests.get(url ,headers = headers)
    # 改变编码
    r.encoding = r.apparent_encoding
    # 提取标题
    title = re.findall(r'<h1>(.*)</h1>', r.text)[0]
    # 懒惰模式匹配文章主题内容, 提取文本内容
    content = re.findall(r'<div id="content" class="showtxt">(.*?)</div>', r.text, flags=re.S)[0].replace('&nbsp;','').replace('<br/>','n')
    return title, content

难点:提取标题和内容(正则表达式部分)

技巧:点开某一章节,光标放在标题,右键-审查元素(找标题的位置)

d5e9d3a10303c7dbd8555f0b55eccafb.png
快速定位标题的位置

技巧:点开某一章节,光标放在正文,右键-审查元素(找正文的位置)

b7334de60fe6c6cb7ab29d005f1608b9.png
快速定位正文的位置

第2步:定义第2个函数,实现功能: 传入一本小说网址, 返回小说章节列表

def get_novel_chapter_link(url):
    """功能: 传入一本小说网址, 返回小说章节列表"""
    import requests 
    import re
    # 添加Hearder
    headers = {'user-agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36'}
    #  
    r = requests.get(url ,headers = headers)
    # 改变编码
    r.encoding = r.apparent_encoding
    #  编写正则表达式进行匹配, 提取章节列表
    chapter_link = re.findall(r'<dd><a href="(.*)".*</dd>' , r.text)
    return chapter_link

第3-1步:实现功能:传入一本网络小说的网址,小说每一章节都独立保存为一个txt文件,到本地文件夹“剑来小说”

# 1. 获取章节列表 http://www.shuquge.com/txt/8659/index.html
chapter_link = get_novel_chapter_link("http://www.shuquge.com/txt/8659/index.html")
import requests 
import os
import re
if not os.path.exists('剑来小说'):
    os.mkdir('剑来小说')
# 2. 对chapter_link 中的链接进行遍历
basic_link = "剑来"
n = 1 # 开始数字
for one_link in chapter_link:
    # 网址的拼接操作
    complete_link =  basic_link + one_link
    # 调用爬取一章内容的函数
    title, content = get_one_page_content(complete_link)
    f = open('./剑来小说/'+ str(n) +'.'+title+'.txt', 'w'  ) # 进入下层目录  title  和 .txt
    f.write(content) # 写入小说内容
    f.close() # 关闭文件
    print('已完成章节:', title)
    n += 1

9071668c83a7107f484ba72d97dfb547.png

第3-2步:实现功能:所有章节保存到一个txt文件中

# 1. 获取章节列表 剑来
chapter_link = get_novel_chapter_link("剑来")
import requests 
import os
import re
if not os.path.exists('剑来小说'):
    os.mkdir('剑来小说')
# 2. 对chapter_link 中的链接进行遍历
basic_link = "剑来"
novel_content = ''
for one_link in chapter_link:
    # 网址的拼接操作
    complete_link =  basic_link + one_link
    # 调用爬取一章内容的函数
    title, content = get_one_page_content(complete_link)
    novel_content =  novel_content+title+'nn'+content+'nn'
#循环外部    
f = open('./剑来小说/'+'剑来.txt', 'w','encoding = utf-8'  ) # 进入下层目录  title  和 .txt
f.write(novel_content) # 写入小说内容
f.close() # 关闭文件

三、方法二:BeautifulSoup方法

  • Beautiful Soup 是一个可以从HTML或XML文件中提取数据的Python库.
  • Beautiful Soup是一个利用HTML或者XML来对内容进行解析的, 解析库
  • HTML的属性都具有结构上的层级关系, 而且有css和id属性, Beautiful Soup就是利用这样的关系进行 提取

4fe0179117d523ad0eb646c41ff94fd9.png
库的安装
import requests
from bs4 import BeautifulSoup

BeautifulSoup库的练习1:诛仙小说

url = "https://www.ibiquge.net/40_40039/19832200.html"
headers ={'User-Agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36'}
r = requests.get(url)
r.encoding = r.apparent_encoding
r

# 利用BeautifulSoup 这个类 ,把源代码创建成 Beautifulsoup 对象

bs = BeautifulSoup(r.text , 'lxml') # 两个参数 1. 把源代码字符串放进去 2 . 解析器

0ded4e621da32d4b0d9f79e6b3dc5d97.png
源代码

d3681758d7fe3bb47ecaa207bf31b15d.png
使用Beautiful库轻轻松松就把标题和内容提取出来了
url = "https://www.ibiquge.net/40_40039/"
headers ={'User-Agent':'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36'}
r = requests.get(url)
r.encoding = r.apparent_encoding
bs = BeautifulSoup(r.text, 'lxml')

40b17865e89de31617f7c5bfb2bcd5f8.png
使用Beautiful库轻轻松松就可以把章节的链接列表提取出来

练习2:童话故事

html = """<html>
<head><title>标题:睡前故事</title></head>
<body>
<p class="title" id="alice">
<b>睡前故事</b>
<i>
作者:佚名
</i>
<i>
年代:未知
</i>
<i>
动机:讲故事
</i>
</p><div>
<a class="littleboy" href="http://example.com/bek" id="link0">罗恩</a>, 
</div>
<div class="good">
<p class="story">很久很久以前, 有三个小女孩; 她们的名字分别叫做
<a class="sister" href="http://example.com/elsie" id="link1">爱丽丝</a>, 
<a class="brother" href="http://example.com/lacie" id="link2">莱希</a> and
<a class="sister" href="http://example.com/tillie" id="link3">蒂莉</a>;
她们居住在井底.</p>
</div>
<p class="story">接下来故事马上就要开始了, 让我们一起走进她们的冒险故事! </p>
</body>
</html>"""

bs = BeautifulSoup(html, 'lxml')

bs.find_all('body') #获取主体部分

bs.find_all('a') #获取链接

bs.find_all(text = '罗恩') #获取文本

bs.find('a' , text = re.compile('爱')) #获取包含某部分文本的内容

bs.find_all('a', class_='brother') #指定class属性

bs.find_all('a', 'brother') #指定class属性

bs.find_all('a','sister')#指定class属性

bs.find_all('a', id='link3') #指定id属性

bs.find_all('a', href="http://example.com/bek") #指定href

7e1faca019c76f5e16d6c2105da26df9.png
1

b3be75dcd546680a794f366bfe52e7b8.png
2

正则表达式与BeautifulSoup库的结合使用

re.compile('bek')

bs.find_all('a', href=re.compile('bek')) #提取链接包含某部分的内容

bs.find('p', 'story') #指定class属性

story.findAll('a', 'brother')[0] #指定class属性

fb84a82c3de895b15e72b3b980cec005.png
正则表达式与BeautifulSoup库的结合使用

24872120c1aae6348efffe299ce45e55.png

四、案例:爬取哪吒之魔童降世电影的短评(利用Beautiful库解析)

哪吒之魔童降世 短评​movie.douban.com

定义函数:实现功能:输入一页短评地址,将短评、有用人数、评论时间、用户名、用户主页、用户头像返回到一个DataFrame中

779ab52531a3d9412b749f561318b656.png
def get_one_page_short(url):
    import requests
    import pandas as pd
    from bs4 import BeautifulSoup

    r = requests.get(url , headers= headers)

    bs = BeautifulSoup(r.text,'lxml')
    # 短评
    short = []
    for i in bs.find_all('span', 'short'):
        short.append(i.text)
    # 有用人数
    votes = []
    for i in bs.find_all('span', 'votes'):
        votes.append(i.text)
    # 评论时间
    comment_time = []
    for i in bs.find_all('span', 'comment-time'):
        comment_time.append(i.text.strip())
    # 用户名
    username = []
    for i in bs.find_all('span', 'comment-info'):
        username.append(i.find('a').text)
    # 用户主页
    index = []
    for i in bs.find_all('span', 'comment-info'):
        index.append(i.find('a')['href'])
    # 用户头像
    img = []
    for i in bs.find_all('div', 'avatar'):
        img.append(i.find('img')['src'])
    # 先新建一个空的DataFrame
    df = pd.DataFrame()
    df['用户名'] = username
    df['评论时间'] = comment_time
    df['有用人数'] = votes
    df['评论内容'] = short
    df['用户主页'] = index
    df['用户头像'] = img
    
    return df

5648e008f01dd9f961983b342d876eb8.png
效果

五、从DataFrame中导出用户头像图片链接,保存到本地

n = 1
import os
if not os.path.exists('用户头像'):
    os.mkdir('用户头像')
for  i in df.用户头像:
    print(i)
    r = requests.get(i , headers = headers)
    f = open('./用户头像/'+str(n)+'.jpg' , 'wb')
    f.write(r.content)
    f.close()
    n += 1
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值