本文目录一览:
- 1、如何用python爬取豆瓣读书的数据
- 2、python bs4怎么抓豆瓣评论做词频表
- 3、Python抓取豆瓣电影排行榜
- 4、python爬虫爬取豆瓣影评返回403怎么办,代理IP和cookie都设置了
- 5、Python爬虫如何抓取豆瓣影评中的所有数据?
- 6、Python豆瓣电影《肖申克的救赎》评论爬取
如何用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] + '\r\n')60 fileTop250.write('电影名称:' + movie[1] + '\r\n')61 fileTop250.write('外文名称:' + movie[2] + '\r\n')62 fileTop250.write('电影别名:' + movie[3] + '\r\n')63 fileTop250.write('导演姓名:' + movie[4] + '\r\n')64 fileTop250.write('参与主演:' + movie[5] + '\r\n')65 fileTop250.write('上映年份:' + movie[6] + '\r\n')66 fileTop250.write('制作国家/地区:' + movie[7] + '\r\n')67 fileTop250.write('电影类别:' + movie[8] + '\r\n')68 fileTop250.write('电影评分:' + movie[9] + '\r\n')69 fileTop250.write('参评人数:' + movie[10] + '\r\n')70 fileTop250.write('简短影评:' + movie[11] + '\r\n\r\n')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')
点击获取源码