本文目錄一覽:
- 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’)
點擊獲取源碼
原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-hant/n/244121.html