爬取豆瓣TOP250并将数据保存为txt文件和csv文件并存入MySQL数据库
生活随笔
收集整理的這篇文章主要介紹了
爬取豆瓣TOP250并将数据保存为txt文件和csv文件并存入MySQL数据库
小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.
項(xiàng)目源碼
import requests # 發(fā)起請(qǐng)求的庫(kù) from fake_useragent import UserAgent # 構(gòu)造user-Agent的庫(kù) import mysql.connector # Python和MySQL連接的庫(kù) from typing import NoReturn, Tuple # 類(lèi)型標(biāo)注的庫(kù) from lxml import etree # 使用lxml提取html的庫(kù) import re # Python中的正則表達(dá)式庫(kù) import csv # 寫(xiě)入csv文件的庫(kù) import time # 程序休眠庫(kù)class bouban_Top250:def __init__(self):"""初始化"""self.conn = mysql.connector.connect( # 構(gòu)造和mysql的連接host='localhost',user='root',passwd='123456',port=3307,charset='utf8',database='reptile')self.my_cursor = self.conn.cursor() # 創(chuàng)建油標(biāo)self.start_id = 1 # 電影id編號(hào)self.all_movies_list = [] # 用來(lái)存儲(chǔ)所有電影信息def send_request(self, url: str) -> str:"""發(fā)送get請(qǐng)求,將HTML頁(yè)面源碼返回url:str類(lèi)型,要請(qǐng)求的鏈接return:str類(lèi)型,請(qǐng)求的鏈接頁(yè)面的html源碼"""# 使用fake_useragent.UserAgent()構(gòu)造請(qǐng)求頭headers = {'user-Agent': UserAgent().Chrome,}# 發(fā)起請(qǐng)求response = requests.get(url=url, headers=headers)# 根據(jù)狀態(tài)碼來(lái)返回HTML頁(yè)面源碼if response.status_code == 200:return response.textelse:print('status_code error')return '-1'def parse_html(self, html: str) -> Tuple[Tuple]:"""解析html源碼html:str類(lèi)型,html頁(yè)面源碼return:Tuple[Tuple],元組中的每一個(gè)元素也是一個(gè)元組,每一個(gè)元素對(duì)應(yīng)一個(gè)電影的所有信息"""# 初始化lxmle = etree.HTML(html, etree.HTMLParser())# 獲取li標(biāo)簽列表,每一個(gè)li標(biāo)簽中包含一個(gè)電影的所有信息li_list = e.xpath('//ol[@class="grid_view"]/li')movies_tuple = []# 遍歷每一個(gè)li標(biāo)簽,對(duì)每一個(gè)li標(biāo)簽進(jìn)行解析for li in li_list:try:name = ''.join(li.xpath('./div/div[@class="info"]/div[@class="hd"]/a/span[@class="title"][1]/text()'))href = ''.join(li.xpath('./div/div[@class="info"]/div[@class="hd"]/a/@href'))performers = ''.join(li.xpath('string(./div/div[@class="info"]/div[@class="bd"]/p[1])'))pattern = re.compile('\n+|\s+')performers = re.sub(pattern=pattern, repl='', string=performers)score = float(''.join(li.xpath('./div/div[@class="info"]/div[@class="bd"]/div[@class="star"]/span[@class="rating_num"]/text()')))quote = ''.join(li.xpath('./div/div[@class="info"]/div[@class="bd"]/p[@class="quote"]/span/text()'))tem = (self.start_id, name, href, performers, score, quote)movies_tuple.append(tem)print(self.start_id, name, href, performers, score, quote, sep=" ")self.start_id += 1except:continuereturn tuple(movies_tuple)def create_table(self, table_name: str) -> NoReturn:"""在mysql數(shù)據(jù)庫(kù)中創(chuàng)建表table_name:str類(lèi)型,要?jiǎng)?chuàng)建表的表名"""sql_create_table = "create table if not exists {}(\ID int ,\mv_name varchar(50),\href varchar(50),\performers varchar(300),\score decimal(3, 1),\quote varchar(50), \primary key (ID)\) ENGINE=INNODB DEFAULT CHARSET='utf8mb4' COLLATE='utf8mb4_unicode_ci'".format(table_name)self.my_cursor.execute(sql_create_table)def insert_to_mysql(self, table_name: str, movies_tuple: Tuple[Tuple]) -> NoReturn:"""將傳入的電影元組中的所有電影插入到表中table_name:str類(lèi)型,要插入信息的表的表名movies_tuple:Tuple[Tuple]類(lèi)型,每一個(gè)元素也是元組,其中包含一個(gè)電影的所有信息"""sql_insert = "insert into {} values (%s, %s, %s, %s, %s, %s)".format(table_name)self.my_cursor.executemany(sql_insert, movies_tuple)self.conn.commit()def append_to_MV_list(self, movies_tuple: Tuple[Tuple]) -> NoReturn:"""將電影元組中的所有電影添加到所有電影列表movies_tuple:Tuple[Tuple]類(lèi)型,要加入的電影元組"""for movie in movies_tuple:self.all_movies_list.append(movie)def writer_into_csv(self, file_name: str, movies_tuple: Tuple[Tuple]) -> NoReturn:"""將傳入的電影元組中的電影寫(xiě)入csv文件file_name:str類(lèi)型,要?jiǎng)?chuàng)建的csv文件的文件名movies_tuple:Tuple[Tuple]類(lèi)型,要寫(xiě)入的電影元組"""headers = ['編號(hào)', '電影名稱(chēng)', '電影鏈接', '演員信息', '豆瓣評(píng)分', '引述']with open(file_name, 'w', encoding='utf-8') as f:writer = csv.writer(f)writer.writerow(headers)writer.writerows(movies_tuple)def writer_into_txt(self, file_name: str, movies_tuple: Tuple[Tuple]) -> NoReturn:"""將傳入的電影元組寫(xiě)入到txt文件中file_name:str類(lèi)型,要?jiǎng)?chuàng)建的txt文件名movies_tuple:Tuple[Tuple]類(lèi)型,要寫(xiě)入的電影元組"""headers = ['編號(hào)', '電影名稱(chēng)', '電影鏈接', '演員信息', '豆瓣評(píng)分', '引述']headers = ' '.join(headers)with open(file_name, 'w', encoding='utf-8') as f:f.write(headers+'\n')for movie in movies_tuple:movie = list(movie)movie[0] = str(movie[0])movie[4] = str(movie[4])movie = str(' '.join(movie))f.write(movie+'\n')def get_next_page_url(self, html: str) -> str:"""從html源碼中獲取下一頁(yè)的鏈接html:str類(lèi)型,獲取下一頁(yè)的html源碼return:str類(lèi)型,構(gòu)造出來(lái)的下一頁(yè)的url"""e = etree.HTML(html, etree.HTMLParser())url = ''.join(e.xpath('//span[@class="next"]/a/@href'))if url:next_page_url = 'https://movie.douban.com/top250{}'.format(url)return next_page_urlelse:return ''if __name__ == '__main__':"""程序入口"""bouban = bouban_Top250()url = 'https://movie.douban.com/top250?start=0&filter='bouban.create_table('douban')while url:html = bouban.send_request(url)url = bouban.get_next_page_url(html)movies_tuple = bouban.parse_html(html)bouban.append_to_MV_list(movies_tuple)time.sleep(1)all_movies_tuple = tuple(bouban.all_movies_list)bouban.insert_to_mysql('douban', all_movies_tuple)bouban.writer_into_txt('douban.txt', all_movies_tuple)bouban.writer_into_csv('douban.csv', all_movies_tuple)準(zhǔn)備工作
- 安裝好程序中用到的第三方庫(kù)
- 安裝好mysql,并將mysql的服務(wù)打開(kāi)
- 在__init__方法初始化中,將mysql的用戶(hù)名和密碼、數(shù)據(jù)庫(kù)更改為自己的,特別是端口號(hào),因?yàn)槲业碾娔X中有兩個(gè)不同的mysql版本,所以我用的端口號(hào)是3307
- 確保自己的電腦有網(wǎng)
- 認(rèn)真看代碼,注釋中都寫(xiě)了代碼的功能,有一些代碼看不懂要去查一查
- 我寫(xiě)本文的日期是2021.03 ,豆瓣更新反爬蟲(chóng)可能會(huì)導(dǎo)致爬取無(wú)效!
結(jié)果展示
心得
- re.sub()方法真是坑,它會(huì)將替換后的文本返回,不會(huì)直接對(duì)原來(lái)的文本做更改,弄得我花了幾十分鐘
- 將文本寫(xiě)入txt文件中不會(huì)自動(dòng)換行,還要自己加換行符,害得我又刪除->更改->刪除…
- 將文本寫(xiě)入txt文件中不指定編碼方式會(huì)導(dǎo)致亂碼,我去
- 你看看下面的結(jié)果:
- 從編寫(xiě)到完成,我的mysql中的表已經(jīng)刪除了不少于20次
總結(jié)
以上是生活随笔為你收集整理的爬取豆瓣TOP250并将数据保存为txt文件和csv文件并存入MySQL数据库的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: AMD内存条:稳定超频、性价比高、细节出
- 下一篇: 修改Mysql表中自增字段的初始值