这篇博客做一个爬虫的实例
今天刚看到一个新闻,在7月26日上映的《哪吒之魔童降世》,密钥第二次延期至10月26日。
截止至9月17日,《哪吒之魔童降世》票房已超49亿票房,在豆瓣上对该电影的评价有好有坏。说实话,博主看了这个电影真的觉得蛮不错的,因此把短评中的差评爬取下来,看下差评包括哪些方面。
一、BeautifulSoup
首先需要了解下差评文字内容在哪些标签下:
进入豆瓣该电影短评界面,检查元素:
可以看出,每一条评论都在一个<div class="comment-item">
标签下,具体的文字内容,在<div class="comment>"
标签下<p>
标签下<span>
标签里。
于是就有了爬取的思路:
- 找到所有的
class=short
的span标签 - 爬取文字内容
- 翻页
(一)导入需要用到的模块与包
import requests
from bs4 import BeautifulSoup
import time
(二)获取差评内容
先爬取一页看下效果
base_url = 'https://movie.douban.com/subject/26794435/comments?start=0&limit=20&sort=new_score&status=P&percent_type=l'
def get_one_pageComments(html):
soup = BeautifulSoup(html.content, 'lxml')
# 可以在这里print下html.content看是否需要添加ua或者cookie爬取
commentsList = soup.find_all('span',class_='short')
pageComments = ""
for commentTag in commentsList:
pageComments += commentTag.text
print(pageComments)
html = requests.get(url)
get_one_pageComments(html)
与原网页对比下:
说明成功爬取到了差评内容
(三)翻页
接下来进行翻页处理,先对比下前三页的url:
发现每翻一页start
的值就加20。翻页功能就可以实现了
base_url = 'https://movie.douban.com/subject/26794435/comments?start={}&limit=20&sort=new_score&status=P&percent_type=l'
for x in range(0, 81, 20):
url = base_url.format(x)
print(url)
综合以上所述,整个流程的代码实现就完成了:
base_url = 'https://movie.douban.com/subject/26794435/comments?start={}&limit=20&sort=new_score&status=P&percent_type=l'
def get_one_pageComments(html):
soup = BeautifulSoup(html.content, 'lxml')
commentsList = soup.find_all('span',class_='short')
pageComments = ""
for commentTag in commentsList:
pageComments += commentTag.text
print(pageComments)
for x in range(0,81, 20):
# 爬取前4页
url = base_url.format(x)
html = requests.get(url)
get_one_pageComments(html)
time.sleep(1)
time.sleep
是避免被识别出在爬取的一个措施。
这样,就完成了对该电影差评的爬取。
二、xpath
其实绝大部分都是一样的,不同之处在于如何定位到差评文本内容。
由于每条差评都在一个<div class="comment">
中,而所有的<div class="comment">
都在<div class="mod-bd">
。
因此,首先要定位到<div class="mod-bd">
,其次定位<div class="comment">
,然后定位<p>
,接着定位<span>
,最后定位text()
思路清晰了,接下来就是代码的实现了:
import requests
from lxml import etree
def get_text(url):
resp = requests.get(url).content.decode('utf-8')
html = etree.HTML(resp)
divs = html.xpath('//div[@class="mod-bd"]/div')
# print(divs)
for div in divs:
pl = div.xpath('//div[@class="comment"]/p/span/text()')
print(pl)
base_url = 'https://movie.douban.com/subject/26794435/comments?start={}&limit=20&sort=new_score&status=P&percent_type=l'
for x in range(0, 81, 20):
url = base_url.format(x)
get_text(url)
爬取后的结果:
三、正则表达式
用正则表达式去匹配一定要记住下面三个非常非常常用且作用十分的匹配式:
.+?
代表所有字符re.VERBOSE
代表正则表达式的注释re.DOTALL
代表.可以匹配所有字符,包括换行符
我们要爬取所有的差评内容,即要找到所有的<div class="comment-item>
。
因此,
用正则表达式定位到<div class="comment-item>
:<div.+?comment-item.+?
然后去定位<div class="comment">
:<div.+?class="comment.+?
再定位到差评内容<span.+?short.+?(.+?)</span>
综上,加上翻页的代码,整理如下:
import requests
import re
def get_text(url):
resp = requests.get(url)
# print(resp.text)
text = resp.text
pl = re.findall(r"""
<div.+?comment-item.+?<div.+?class="comment.+?<span.+?short.+?(.+?)</span>
""",text,re.VERBOSE|re.DOTALL)
print(pl)
base_url = 'https://movie.douban.com/subject/26794435/comments?start={}&limit=20&sort=new_score&status=P&percent_type=l'
for x in range(0, 81, 20):
url = base_url.format(x)
get_text(url)
虽然分别用BeautifulSoup、Xpath、正则表达式基本实现了对差评内容的爬取,但是不足之处在于没有对爬取到的str进行保存,是因为博主在保存时总是报错。。还没有找到合适的解决办法,后续会进行完善。