Python爬蟲實戰專案之小說資訊爬取
阿新 • • 發佈:2019-01-03
我們以奇書網為例進行爬取
一,先新建一個新的資料夾,名字自取,用於存放py檔案和爬取的資料
二,找到要爬取的網站的ur和你自己瀏覽器的請求頭,(因為我是以奇書網為例,瀏覽器為火狐瀏覽器)
url= ‘https://www.qisuu.la/soft/sort01/’
請求頭:‘User_Anger’: 'Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:61.0) Gecko/20100101 Firefox/61.0'
( 找不到請求頭的可以直接拿去用)
三,開始爬取
1建立一個類,並.定義初始化函式,在初始化函式中定義好url和請求頭,由於下面要用到的資料較多,所以我定義的比較多,程式碼如下:
class NovelSpider(object): def __init__(self): self.url = 'https://www.qisuu.la/soft/sort01/' self.html = '' self.herders = { 'User_Anger': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64; rv:61.0) Gecko/20100101 Firefox/61.0' } self.total = 0 self.count = 0 self.retry_count = 0 #建立Excel表格,用於儲存爬取的資料 self.workbook = xlwt.Workbook(encoding='utf-8') self.sheet = self.workbook.add_sheet('novel_data') self.create_excel()
2,建立Excel表,用於儲存爬取的資料
def create_excel(self): self.sheet.write(0, 0, '小說名稱') self.sheet.write(0, 1, '點選次數') self.sheet.write(0, 2, '文字大小') self.sheet.write(0, 3, '書籍型別') self.sheet.write(0, 4, '更新日期') self.sheet.write(0, 5, '連載狀態') self.sheet.write(0, 6, '書籍作者') self.sheet.write(0, 7, '執行環境') self.sheet.write(0, 8, '小說簡介') self.sheet.write(0, 9, '下載地址')
3.模擬瀏覽器傳送請求,並接受返回的網頁原始碼,程式碼如下:
def get_html(self, url):
# 1.建立request物件,設定隨機請求頭
req = request.Request(url=url, headers={
'User-Agent': choice(self.ua_list)
})
try:
self.retry_count += 1
# 2.發起請求
response = request.urlopen(req)
# 3.接收資料
self.html = response.read().decode('utf-8')
except Exception as e:
# 請求重試次數大於3,放棄該請求
if self.retry_count > 3:
print('請求失敗,地址:{}'.format(url))
return
# 重新發送請求
print('請求資料失敗,正在嘗試重新連線...')
self.get_html(url)
else:
# 歸0
self.retry_count = 0
4.用正則表示式來解析網頁原始碼,並獲取小說詳情頁的連結,程式碼如下:
def get_story_link(self):
"""獲取小說頁面連結"""
#用正則從網頁原始碼中匹配小說頁面的連結
pattern = re.compile(r'<li>.*?<div class="s.*?<a href="(.*?)">.*?"',re.S)
res = re.findall(pattern,self.html)
if res:
"""遍歷小說連結"""
for x in res:
#拼接新的連結,並傳入請求函式中
url =self.url2 + x
self.get_html(url)
# #解析小說網頁資料
self.parse_story()
5.解析小說網頁的資料,拿到自己想要的資料,程式碼如下:
(我們在這裡找了小說資訊的部分資料)
def parse_story(self):
"""解析小說頁面的資料"""
#運用正則來匹配自己想要的資料
pattern = re.compile(r'.*?detail_right".*?h1>(.*?)</h1.*?ul>.*?<li.*?:(.*?)<.*?:(.*?)<.*?:(.*?)<.*?:(.*?)<.*?:(.*?)<.*?:(.*?)<.*?:(.*?)<.*?showInfo".*?p>(.*?)</p.*?', re.S)
res = re.findall(pattern, self.html)
# for x in res:
# print(res)
#提取資料
title = res[0][0]
click_num = res[0][1]
size = res[0][2]
novel_type =res[0][3]
datetime =res[0][4]
status =res[0][5]
author =res[0][6]
run_sys =res[0][7]
content =res[0][8]
#儲存資料
self.save_date(title,click_num,size,novel_type,datetime,status,author,run_sys,content)
6,儲存資料,儲存到Excel表中,程式碼如下:
def write_to_excel(self, idx, data):
#封裝寫入表格的函式
print(idx, data)
self.sheet.write(self.count, idx, data)
def save_data(self, *args):
self.count += 1
print('正在儲存第{}本小說:{}'.format(self.count, args[0]))
# 1.基礎寫法
self.sheet.write(self.count, 0, args[0])
self.sheet.write(self.count, 1, args[1])
self.sheet.write(self.count, 2, args[2])
self.sheet.write(self.count, 3, args[3])
self.sheet.write(self.count, 4, args[4])
self.sheet.write(self.count, 5, args[5])
self.sheet.write(self.count, 6, args[6])
self.sheet.write(self.count, 7, args[7])
self.sheet.write(self.count, 8, args[8])
self.sheet.write(self.count, 9, args[9])
# 2.進階寫法
# *args 將元組看做一個容器,進行列舉
# for idx, data in enumerate(args):
# if idx == 8:
# data = data.replace(' ', ' ')
#
# self.write_to_excel(idx, data)
# 3.終極寫法
# rs = map(lambda idx, data: self.sheet.write(self.count, idx, data), range(10), args)
# for x in rs:
# pass
self.workbook.save('小說資料.xls')
7.執行函式:
def run(self):
#想獲取多少頁的資料 就把range函式裡面的後面的數字改一下
for x in range(1, 11):
print(''.center(50,'*'))
print('正在獲取第%s頁資料,請稍後....' % (x))
# 拼接完整的url地址
url = t_info[0] + 'index_{}.html'.format(x)
# 獲取該頁原始碼
self.get_html(url)
# 解析原始碼,提取資料
self.parse_index()
break
self.workbook.save('小說資料.xls')
以上就是爬取小說的全部步驟,全部程式碼如下:
# -*- coding: utf-8 -*-
__author__ = 'wj'
__date__ = '2018/8/10 9:08'
import re
from random import choice
from urllib import request
import xlwt
class NovelSpider(object):
def __init__(self):
self.url = 'https://www.qisuu.la/soft/sort01/'
self.html = ''
self.ua_list = [
'Mozilla/5.0 (Windows NT 10.0; WOW64; rv:52.0) Gecko/20100101 Firefox/52.0',
'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.106 Safari/537.36',
'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/534.57.2 (KHTML, like Gecko) Version/5.1.7 Safari/534.57.2',
'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/30.0.1599.101 Safari/537.36',
'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/38.0.2125.122 UBrowser/4.0.3214.0 Safari/537.36'
]
self.total = 0
self.count = 0
self.retry_count = 0
self.workbook = xlwt.Workbook(encoding='utf-8')
self.sheet = self.workbook.add_sheet('novel_data')
self.create_excel()
def create_excel(self):
self.sheet.write(0, 0, '小說名稱')
self.sheet.write(0, 1, '點選次數')
self.sheet.write(0, 2, '文字大小')
self.sheet.write(0, 3, '書籍型別')
self.sheet.write(0, 4, '更新日期')
self.sheet.write(0, 5, '連載狀態')
self.sheet.write(0, 6, '書籍作者')
self.sheet.write(0, 7, '執行環境')
self.sheet.write(0, 8, '小說簡介')
self.sheet.write(0, 9, '下載地址')
def get_html(self, url):
# 1.建立request物件,設定隨機請求頭
req = request.Request(url=url, headers={
'User-Agent': choice(self.ua_list)
})
try:
self.retry_count += 1
# 2.發起請求
response = request.urlopen(req)
# 3.接收資料
self.html = response.read().decode('utf-8')
except Exception as e:
# 請求重試次數大於3,放棄該請求
if self.retry_count > 3:
print('請求失敗,地址:{}'.format(url))
return
# 重新發送請求
print('請求資料失敗,正在嘗試重新連線...')
self.get_html(url)
else:
# 歸0
self.retry_count = 0
def get_total(self):
# 1.獲取原始碼
self.get_html(self.url)
# 2.準備正則
pattern = re.compile(r'<div class="tspage.*?/(.*?) ', re.S)
# 3.搜尋
rs = re.search(pattern, self.html)
if rs:
self.total = int(rs.group(1))
print(self.total)
def parse_index(self):
# 1.準備正則
pattern = re.compile(r'<li.*?<div.*?class="s".*?<a href="(.*?)"', re.S)
# 2.搜尋資料
results = re.findall(pattern, self.html)
# 3.迴圈遍歷每一個小連結
for link in results:
url = 'https://www.qisuu.la' + link
# 4.獲取詳情頁面的原始碼
self.get_html(url)
# 5.解析詳情頁面資料
self.parse_detail()
def parse_detail(self):
#1 準備正則
pattern = re.compile(r"""<div class="detail_right.*?<h1>(.*?)</h1.*?<li.*?:(.*?)<.*?:(.*?)<.*?:(.*?)<.*?:(.*?)<.*?:(.*?)<.*?:(.*?)<.*?:(.*?)<.*?<div class="showInfo".*?<p.*?>(.*?)</p.*?get_down_url.*?,'(.*?)'""", re.S)
results = re.findall(pattern, self.html)
# 1.提取資料
title = results[0][0]
click_num = results[0][1]
file_size = results[0][2]
novel_type = results[0][3]
datetime = results[0][4]
status = results[0][5]
author = results[0][6]
run_sys = results[0][7]
description = results[0][8].replace(' ',' ')
download = results[0][9]
# 儲存資料
self.save_data(title, click_num, file_size, novel_type, datetime, status, author, run_sys, description, download)
# 封裝寫入excel表格的函式
def write_to_excel(self, idx, data):
print(idx, data)
self.sheet.write(self.count, idx, data)
def save_data(self, *args):
self.count += 1
print('正在儲存第{}本小說:{}'.format(self.count, args[0]))
# 1.基礎寫法
self.sheet.write(self.count, 0, args[0])
self.sheet.write(self.count, 1, args[1])
self.sheet.write(self.count, 2, args[2])
self.sheet.write(self.count, 3, args[3])
self.sheet.write(self.count, 4, args[4])
self.sheet.write(self.count, 5, args[5])
self.sheet.write(self.count, 6, args[6])
self.sheet.write(self.count, 7, args[7])
self.sheet.write(self.count, 8, args[8])
self.sheet.write(self.count, 9, args[9])
# 2.進階寫法
# *args 將元組看做一個容器,進行列舉
# for idx, data in enumerate(args):
# if idx == 8:
# data = data.replace(' ', ' ')
#
# self.write_to_excel(idx, data)
# 3.終極寫法
# rs = map(lambda idx, data: self.sheet.write(self.count, idx, data), range(10), args)
# for x in rs:
# pass
self.workbook.save('小說資料.xls')
def parse_type(self):
pattern = re.compile(r'<div class="nav">(.*?)</div>', re.S)
res = re.search(pattern, self.html)
if res:
html = res.group(1)
results = re.findall(re.compile(r'<a.*? href="(.*?)".*?>(.*?)</a>',re.S), html)
# 返回所有分類地址
# x是一個小元組
return map(lambda x: ('https://www.qisuu.la'+x[0],x[1]), results[1:])
def run(self):
# 獲取總頁碼
self.get_total()
# 獲取所有分類地址
types = self.parse_type()
for t_info in types:
# print(t_info)
print('正在爬取{}下的小說.....'.format(t_info[1]))
for x in range(1, self.total + 1):
print(''.center(50,'*'))
print('正在獲取%s下的第%s頁資料,請稍後....' % (t_info[1], x))
# 拼接完整的url地址
url = t_info[0] + 'index_{}.html'.format(x)
# 獲取該頁原始碼
self.get_html(url)
# 解析原始碼,提取資料
self.parse_index()
break
self.workbook.save('小說資料.xls')
if __name__ == '__main__':
novel = NovelSpider()
novel.run()