首页 > 编程知识 正文

python登录豆瓣并爬取影评(python爬取豆瓣短评)

时间:2023-12-11 16:24:14 阅读:314537 作者:GDLW

本文目录一览:

如何用python爬取豆瓣读书的数据

这两天爬了豆瓣读书的十万条左右的书目信息,用时将近一天,现在趁着这个空闲把代码总结一下,还是菜鸟,都是用的最简单最笨的方法,还请路过的大神不吝赐教。

第一步,先看一下我们需要的库:

import requests                       #用来请求网页

from bs4 import BeautifulSoup         #解析网页

import time          #设置延时时间,防止爬取过于频繁被封IP号

import re            #正则表达式库

import pymysql       #由于爬取的数据太多,我们要把他存入MySQL数据库中,这个库用于连接数据库

import random        #这个库里用到了产生随机数的randint函数,和上面的time搭配,使爬取间隔时间随机

这个是豆瓣的网址:x-sorttags-all

我们要从这里获取所有分类的标签链接,进一步去爬取里面的信息,代码先贴上来:

import requests

from bs4 import BeautifulSoup       #导入库

url="httom/tag/?icn=index-nav"

wb_data=requests.get(url)                #请求网址

soup=BeautifulSoup(wb_data.text,"lxml")  #解析网页信息

tags=soup.select("#content div div.article div div table tbody tr td a")

#根据CSS路径查找标签信息,CSS路径获取方法,右键-检查-copy selector,tags返回的是一个列表

for tag in tags:

tag=tag.get_text()    #将列表中的每一个标签信息提取出来

helf="hom/tag/"

#观察一下豆瓣的网址,基本都是这部分加上标签信息,所以我们要组装网址,用于爬取标签详情页

url=helf+str(tag)

print(url)    #网址组装完毕,输出

以上我们便爬取了所有标签下的网址,我们将这个文件命名为channel,并在channel中创建一个channel字符串,放上我们所有爬取的网址信息,等下爬取详情页的时候直接从这里提取链接就好了,如下:

channel='''

tag/程序

'''

现在,我们开始第二个程序。

QQ图片20160915233329.png

标签页下每一个图片的信息基本都是这样的,我们可以直接从这里提取到标题,作者,出版社,出版时间,价格,评价人数,以及评分等信息(有些外国作品还会有译者信息),提取方法与提取标签类似,也是根据CSS路径提取。

我们先用一个网址来实验爬取:

url="htt/tag/科技"

wb_data = requests.get(url)

soup = BeautifulSoup(wb_data.text.encode("utf-8"), "lxml")

tag=url.split("?")[0].split("/")[-1]    #从链接里面提取标签信息,方便存储

detils=soup.select("#subject_list ul li div.info div.pub")  #抓取作者,出版社信息,稍后我们用spite()函数再将他们分离出来

scors=soup.select("#subject_list ul li div.info div.star.clearfix span.rating_nums")   #抓取评分信息

persons=soup.select("#subject_list ul li div.info div.star.clearfix span.pl")    #评价人数

titles=soup.select("#subject_list ul li div.info h2 a")   #书名

#以上抓取的都是我们需要的html语言标签信息,我们还需要将他们一一分离出来

for detil,scor,person,title in zip(detils,scors,persons,titles):

#用一个zip()函数实现一次遍历

#因为一些标签中有译者信息,一些标签中没有,为避免错误,所以我们要用一个try来把他们分开执行

try:

author=detil.get_text().split("/",4)[0].split()[0]     #这是含有译者信息的提取办法,根据“/”  把标签分为五部分,然后依次提取出来

yizhe= detil.get_text().split("/", 4)[1]

publish=detil.get_text().split("/", 4)[2]

time=detil.get_text().split("/", 4)[3].split()[0].split("-")[0]   #时间我们只提取了出版年份

price=ceshi_priceone(detil)        #因为价格的单位不统一,我们用一个函数把他们换算为“元”

scoe=scor.get_text() if True else ""    #有些书目是没有评分的,为避免错误,我们把没有评分的信息设置为空

person=ceshi_person(person)      #有些书目的评价人数显示少于十人,爬取过程中会出现错误,用一个函数来处理

title=title.get_text().split()[0]  

#当没有译者信息时,会显示IndexError,我们分开处理

except IndexError:

try:

author=detil.get_text().split("/", 3)[0].split()[0]

yizhe=""         #将detil信息划分为4部分提取,译者信息直接设置为空,其他与上面一样

publish=detil.get_text().split("/", 3)[1]

time=detil.get_text().split("/", 3)[2].split()[0].split("-")[0]

price=ceshi_pricetwo(detil)

scoe=scor.get_text() if True else ""

person=ceshi_person(person)

title=title.get_text().split()[0]

except (IndexError,TypeError):

continue  

#出现其他错误信息,忽略,继续执行(有些书目信息下会没有出版社或者出版年份,但是数量很少,不影响我们大规模爬取,所以直接忽略)

except TypeError:

continue

#提取评价人数的函数,如果评价人数少于十人,按十人处理

def ceshi_person(person):

try:

person = int(person.get_text().split()[0][1:len(person.get_text().split()[0]) - 4])

except ValueError:

person = int(10)

return person

#分情况提取价格的函数,用正则表达式找到含有特殊字符的信息,并换算为“元”

def ceshi_priceone(price):

price = detil.get_text().split("/", 4)[4].split()

if re.match("USD", price[0]):

price = float(price[1]) * 6

elif re.match("CNY", price[0]):

price = price[1]

elif re.match("A$", price[0]):

price = float(price[1:len(price)]) * 6

else:

price = price[0]

return price

def ceshi_pricetwo(price):

price = detil.get_text().split("/", 3)[3].split()

if re.match("USD", price[0]):

price = float(price[1]) * 6

elif re.match("CNY", price[0]):

price = price[1]

elif re.match("A$", price[0]):

price = float(price[1:len(price)]) * 6

else:

price = price[0]

return price

实验成功后,我们就可以爬取数据并导入到数据库中了,以下为全部源码,特殊情况会用注释一一说明。

import requests

from bs4 import BeautifulSoup

import time

import re

import pymysql

from channel import channel   #这是我们第一个程序爬取的链接信息

import random

def ceshi_person(person):

try:

person = int(person.get_text().split()[0][1:len(person.get_text().split()[0]) - 4])

except ValueError:

person = int(10)

return person

def ceshi_priceone(price):

price = detil.get_text().split("/", 4)[4].split()

if re.match("USD", price[0]):

price = float(price[1]) * 6

elif re.match("CNY", price[0]):

price = price[1]

elif re.match("A$", price[0]):

price = float(price[1:len(price)]) * 6

else:

price = price[0]

return price

def ceshi_pricetwo(price):

price = detil.get_text().split("/", 3)[3].split()

if re.match("USD", price[0]):

price = float(price[1]) * 6

elif re.match("CNY", price[0]):

price = price[1]

elif re.match("A$", price[0]):

price = float(price[1:len(price)]) * 6

else:

price = price[0]

return price

#这是上面的那个测试函数,我们把它放在主函数中

def mains(url):

wb_data = requests.get(url)

soup = BeautifulSoup(wb_data.text.encode("utf-8"), "lxml")

tag=url.split("?")[0].split("/")[-1]

detils=soup.select("#subject_list ul li div.info div.pub")

scors=soup.select("#subject_list ul li div.info div.star.clearfix span.rating_nums")

persons=soup.select("#subject_list ul li div.info div.star.clearfix span.pl")

titles=soup.select("#subject_list ul li div.info h2 a")

for detil,scor,person,title in zip(detils,scors,persons,titles):

l = []  #建一个列表,用于存放数据

try:

author=detil.get_text().split("/",4)[0].split()[0]

yizhe= detil.get_text().split("/", 4)[1]

publish=detil.get_text().split("/", 4)[2]

time=detil.get_text().split("/", 4)[3].split()[0].split("-")[0]

price=ceshi_priceone(detil)

scoe=scor.get_text() if True else ""

person=ceshi_person(person)

title=title.get_text().split()[0]

except IndexError:

try:

author=detil.get_text().split("/", 3)[0].split()[0]

yizhe=""

publish=detil.get_text().split("/", 3)[1]

time=detil.get_text().split("/", 3)[2].split()[0].split("-")[0]

price=ceshi_pricetwo(detil)

scoe=scor.get_text() if True else ""

person=ceshi_person(person)

title=title.get_text().split()[0]

except (IndexError,TypeError):

continue  

except TypeError:

continue

l.append([title,scoe,author,price,time,publish,person,yizhe,tag])

#将爬取的数据依次填入列表中

sql="INSERT INTO allbooks values(%s,%s,%s,%s,%s,%s,%s,%s,%s)"  #这是一条sql插入语句

cur.executemany(sql,l)   #执行sql语句,并用executemary()函数批量插入数据库中

conn.commit()

#主函数到此结束

# 将Python连接到MySQL中的python数据库中

conn = pymysql.connect( user="root",password="123123",database="python",charset='utf8')

cur = conn.cursor()

cur.execute('DROP TABLE IF EXISTS allbooks')   #如果数据库中有allbooks的数据库则删除

sql = """CREATE TABLE allbooks(

title CHAR(255) NOT NULL,

scor CHAR(255),

author CHAR(255),

price CHAR(255),

time CHAR(255),

publish CHAR(255),

person CHAR(255),

yizhe CHAR(255),

tag CHAR(255)

)"""

cur.execute(sql)  #执行sql语句,新建一个allbooks的数据库

start = time.clock()   #设置一个时钟,这样我们就能知道我们爬取了多长时间了

for urls in channel.split():

urlss=[urls+"?start={}type=T".format(str(i)) for i in range(0,980,20)]   #从channel中提取url信息,并组装成每一页的链接

for url in urlss:

mains(url)       #执行主函数,开始爬取

print(url)        #输出要爬取的链接,这样我们就能知道爬到哪了,发生错误也好处理

time.sleep(int(format(random.randint(0,9))))   #设置一个随机数时间,每爬一个网页可以随机的停一段时间,防止IP被封

end = time.clock()

print('Time Usage:', end - start)    #爬取结束,输出爬取时间

count = cur.execute('select * from allbooks')

print('has %s record' % count)       #输出爬取的总数目条数

# 释放数据连接

if cur:

cur.close()

if conn:

conn.close()

这样,一个程序就算完成了,豆瓣的书目信息就一条条地写进了我们的数据库中,当然,在爬取的过程中,也遇到了很多问题,比如标题返回的信息拆分后中会有空格,写入数据库中会出现错误,所以只截取了标题的第一部分,因而导致数据库中的一些书名不完整,过往的大神如果有什么办法,还请指教一二。

等待爬取的过程是漫长而又欣喜的,看着电脑上一条条信息被刷出来,成就感就不知不觉涌上心头;然而如果你吃饭时它在爬,你上厕所时它在爬,你都已经爬了个山回来了它还在爬时,便会有点崩溃了,担心电脑随时都会坏掉(还是穷学生换不起啊啊啊啊~)

所以,还是要好好学学设置断点,多线程,以及正则,路漫漫其修远兮,吾将上下而求索~共勉~

python bs4怎么抓豆瓣评论做词频表

根据词频生成词云。

该程序进行爬取豆瓣热评,将爬取的评论(json文件)保存到与该python文件同一级目录下注意需要下载这几个库:requests、lxml、json、time,该程序将json中的数据进行处理,提取重要信息,并用wordcloud库制作词云图片,同样保存到与该python文件同一级目录下注意需要下载这几个库:jieba、wordcloud、json。

Python是一种跨平台的计算机程序设计语言是一个高层次的结合了解释性、编译性、互动性和面向对象的脚本语言最初被设计用于编写自动化脚本(shell),随着版本的不断更新和语言新功能的添加,越多被用于独立的、大型项目的开发。

Python抓取豆瓣电影排行榜

1.观察url

首先观察一下网址的结构 ;filter=type= :

可以看到,问号?后有三个参数 start、filter、type,其中start代表页码,每页展示25部电影,0代表第一页,以此类推25代表第二页,50代表第三页...

filter顾名思义,是过滤已经看过的电影,filter和type在这里不重要,可以不管。

2.查看网页源代码

打开上面的网址,查看源代码,可以看到信息的展示结构如下:

1 ol class="grid_view" 2 li 3 div class="item" 4 div class="pic" 5 em class=""1/em 6 a href="" 7 img alt="肖申克的救赎" src="" class="" 8 /a 9 /div10 div class="info"11 div class="hd"12 a href="" class=""13 span class="title"肖申克的救赎/span14 span class="title" / The Shawshank Redemption/span15 span class="other" / 月黑高飞(港) / 刺激1995(台)/span16 /a17 18 19 span class="playable"[可播放]/span20 /div21 div class="bd"22 p class=""23 导演: 弗兰克·德拉邦特 Frank Darabont 主演: 蒂姆·罗宾斯 Tim Robbins /...br24 1994 / 美国 / 犯罪 剧情25 /p26 27 28 div class="star"29 span class="rating5-t"em9.6/em/span30 span646374人评价/span31 /div32 33 p class="quote"34 span class="inq"希望让人自由。/span35 /p36 /div37 /div38 /div39 /li

其中em class=""1/em代表排名,span class="title"肖申克的救赎/span代表电影名,其他信息的含义也很容易能看出来。

于是接下来可以写正则表达式:

1 pattern = re.compile(u'div.*?class="item".*?div.*?class="pic".*?' 2 + u'em.*?class=""(.*?)/em.*?' 3 + u'div.*?class="info".*?span.*?class="title"(.*?)' 4 + u'/span.*?span.*?class="title"(.*?)/span.*?' 5 + u'span.*?class="other"(.*?)/span.*?/a.*?' 6 + u'div.*?class="bd".*?p.*?class="".*?' 7 + u'导演: (.*?) ' 8 + u'主演: (.*?)br' 9 + u'(.*?) / (.*?) / '10 + u'(.*?)/p'11 + u'.*?div.*?class="star".*?em(.*?)/em'12 + u'.*?span(.*?)人评价/span.*?p.*?class="quote".*?'13 + u'span.*?class="inq"(.*?)/span.*?/p', re.S)

在此处flag参数re.S代表多行匹配。

3.使用面向对象的设计模式编码

代码如下:

1 # -*- coding:utf-8 -*- 2 __author__ = 'Jz' 3 import urllib2 4 import re 5 import sys 6 7 class MovieTop250: 8 def __init__(self): 9 #设置默认编码格式为utf-810 reload(sys)11 sys.setdefaultencoding('utf-8')12 self.start = 013 self.param = 'filter=type='14 self.headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64)'}15 self.movieList = []16 self.filePath = 'D:/coding_file/python_file/File/DoubanTop250.txt'17 18 def getPage(self):19 try:20 URL = '' + str(self.start)21 request = urllib2.Request(url = URL, headers = self.headers)22 response = urllib2.urlopen(request)23 page = response.read().decode('utf-8')24 pageNum = (self.start + 25)/2525 print '正在抓取第' + str(pageNum) + '页数据...' 26 self.start += 2527 return page28 except urllib2.URLError, e:29 if hasattr(e, 'reason'):30 print '抓取失败,具体原因:', e.reason31 32 def getMovie(self):33 pattern = re.compile(u'div.*?class="item".*?div.*?class="pic".*?'34 + u'em.*?class=""(.*?)/em.*?'35 + u'div.*?class="info".*?span.*?class="title"(.*?)'36 + u'/span.*?span.*?class="title"(.*?)/span.*?'37 + u'span.*?class="other"(.*?)/span.*?/a.*?'38 + u'div.*?class="bd".*?p.*?class="".*?'39 + u'导演: (.*?) '40 + u'主演: (.*?)br'41 + u'(.*?) / (.*?) / '42 + u'(.*?)/p'43 + u'.*?div.*?class="star".*?em(.*?)/em'44 + u'.*?span(.*?)人评价/span.*?p.*?class="quote".*?'45 + u'span.*?class="inq"(.*?)/span.*?/p', re.S)46 while self.start = 225:47 page = self.getPage()48 movies = re.findall(pattern, page)49 for movie in movies:50 self.movieList.append([movie[0], movie[1], movie[2].lstrip(' / '),

51 movie[3].lstrip(' / '), movie[4],

52 movie[5], movie[6].lstrip(), movie[7], movie[8].rstrip(),53 movie[9], movie[10], movie[11]])54 55 def writeTxt(self):56 fileTop250 = open(self.filePath, 'w')57 try:58 for movie in self.movieList:59 fileTop250.write('电影排名:' + movie[0] + 'rn')60 fileTop250.write('电影名称:' + movie[1] + 'rn')61 fileTop250.write('外文名称:' + movie[2] + 'rn')62 fileTop250.write('电影别名:' + movie[3] + 'rn')63 fileTop250.write('导演姓名:' + movie[4] + 'rn')64 fileTop250.write('参与主演:' + movie[5] + 'rn')65 fileTop250.write('上映年份:' + movie[6] + 'rn')66 fileTop250.write('制作国家/地区:' + movie[7] + 'rn')67 fileTop250.write('电影类别:' + movie[8] + 'rn')68 fileTop250.write('电影评分:' + movie[9] + 'rn')69 fileTop250.write('参评人数:' + movie[10] + 'rn')70 fileTop250.write('简短影评:' + movie[11] + 'rnrn')71 print '文件写入成功...'72 finally:73 fileTop250.close()74 75 def main(self):76 print '正在从豆瓣电影Top250抓取数据...'77 self.getMovie()78 self.writeTxt()79 print '抓取完毕...'80 81 DouBanSpider = MovieTop250()82 DouBanSpider.main()

代码比较简单,最后将信息写入一个文件,没有什么需要解释的地方。

python爬虫爬取豆瓣影评返回403怎么办,代理IP和cookie都设置了

如果只是爬取影评的话,没必要登录。

返回的304是你的cookie用的是旧的。

去掉cookie,正常抓取就可以了。

Python爬虫如何抓取豆瓣影评中的所有数据?

你可以用前嗅爬虫采集豆瓣的影评,我之前用的,还可以过滤只采集评分在6分以上的所有影评,非常强大,而且他们软件跟数据库对接,采集完数据后,直接入库,导出excel表。很省心。

Python豆瓣电影《肖申克的救赎》评论爬取

先看效果图:

地址:( ;status=P)

爬取前1w条评论

存储成txt文档

数据预处理

中文分词

统计top10的高频词

可视化展示高频词

根据词频生成词云

审核评论

================================================================

配置准备

中文分词需要jieba

词云绘制需要wordcloud

可视化展示中需要的中文字体

网上公开资源中找一个中文停用词表

根据分词结果自己制作新增词表

准备一张词云背景图(附加项,不做要求)

paddlehub配置

#安装jieba分词和词云

pip install jieba

pip install wordcloud

#安装paddle

pip install --upgrade PaddlePaddle

#安装模型

#hub install porn_detection_lstm==1.1.0

pip install --upgrade paddlehub

pip install  numpy

#安装Beautifulsoup

pip install BeautifulSoup4

Github地址:

有可能遇到的问题:

1.UnicodeDecodeError: 'utf-8' codec can't decode byte 0xe8 in position 1: invalid continuation byte

解决方法:

1.不使用urlLib换做requests

2.去掉请求头中的 'Accept-Encoding': 'gzip, deflate, br'

3.返回值reponse 转字符串指定编码utf-8

# 'Accept-Encoding': 'gzip, deflate, br',

2.关于cookie

解决方法:

1.去豆瓣请求头中复制cookie设置到请求头中

'Cookie': 'bid=WD6_t6hVqgM'

3.请求返回418的问题

解决方案模拟设置请求头,设置user-agent

'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.81 Safari/537.36',

4.使用beautifulsoup获取不到评论

解决方法:

第一步:指定解析参数为'lxml'

soupComment = BeautifulSoup(html, 'lxml')

第二步:

findAll方法指定css文件的class名

print('网页内容:', soupComment.prettify())

comments = soupComment.findAll(class_='short')

点击获取源码

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。