前一段时间看了B站有关爬虫的视频,自己也想练练手.就抓抓知轩藏书上书籍的评分情况.
关于评分(投票)的内容,是个javascrip编的模块,开始用request抓的时候,没抓到内容.最近学习到了怎么抓js的内容,又想试试看了.
看知轩藏书书籍的链接,就会发现每本书都对应一个编号,如"http://www.zxcs.me/post/12071"
这样我们就可以按照编号来抓
1.获取最新书籍的编号
def get_max():
"""
获取最新收录的小说的编号
:return:
"""
firsturl="http://www.zxcs.me/"
html = requests.get(firsturl,headers = head)
html.encoding = 'utf8'
soup=BeautifulSoup(html.text,'lxml')
max_data = soup.select('body > div.wrap > div:nth-child(1) > div.box > ul > li:nth-child(1) > a')
data=str(max_data[0])
# print(max_data[0])
# print(type(max_data))
findlink = re.compile(r'<a href="(.*?)">')
link = re.findall(findlink, data) #获取小说的超链接
find_cnt=re.compile(r'(?<=post/)\d+\.?\d*')
cnt = re.findall(find_cnt,link[0]) #抓取超链接里面的数字,即编号
return int(cnt[0])
抓取书名/作者的信息
def get_name(number):
"""
提取小说的书名和作者
:param number: 小说编号
:return: 书名和作者
"""
url = 'http://www.zxcs.me/post/'
novel_url = url+str(number)
html = ask_url(novel_url)
soup = BeautifulSoup(html,'lxml')
title = str(soup.select('#content > h1 ')[0]) #小说的名字啊的信息
find_name = re.compile(r'《(.*)》') # 提取书名,即<<>>之间的内容
name = re.findall(find_name,title)[0]
find_author = re.compile(r':(.+?)<')
author = re.findall(find_author,title)[0] #提取作者
return name,author
然后就是获取评分的信息
def get_rank(number):
"""
获取小说的评价(投票的结果)
:param number:
:return: 投票的结果
"""
voteurl = 'http://www.zxcs.me/content/plugins/cgz_xinqing/cgz_xinqing_action.php?action=show&id={}'.format(number)
vote_html = requests.get(voteurl, headers=head)
data1 = vote_html.text
data_split = data1.split(",")
# print(data_split)
rank_data = []
for item in data_split:
rank = int(item)
rank_data.append(rank)
return rank_data
然后就是数据处理,存文件啊啥的
全部的代码
import re # 正则表达式 进行文字匹配
import urllib.request # 指定url 获取网页数据
from bs4 import BeautifulSoup #网页解析,获取数据
import lxml
import xlwt # 进行excel 操作
import sqlite3 # sqlite3 数据库 操作
import requests
import pandas as pd
import time
head = { # 模拟浏览器头部信息
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/84.0.4147.105 Safari/537.36 Edg/84.0.522.58"
} # 用户代理,告诉服务器浏览器的类型
def main():
dbpath ="D:\云盘\我的坚果云\Python\practice\PythonWebSpiderCrashCourseInFiveDay\getDoubanData\zxcs100.db"
# init_db(dbpath)
# 1 爬取网页
max_novel=get_max()
# 2 解析数据
result = dealData(1000, max_novel)
print(list)
# 3 保存数据
write2Csv(result)
write2X(result)
def get_max():
"""
获取最新收录的小说的编号
:return:
"""
firsturl="http://www.zxcs.me/"
html = requests.get(firsturl,headers = head)
html.encoding = 'utf8'
soup=BeautifulSoup(html.text,'lxml')
max_data = soup.select('body > div.wrap > div:nth-child(1) > div.box > ul > li:nth-child(1) > a')
data=str(max_data[0])
# print(max_data[0])
# print(type(max_data))
findlink = re.compile(r'<a href="(.*?)">')
link = re.findall(findlink, data) #获取小说的超链接
find_cnt=re.compile(r'(?<=post/)\d+\.?\d*')
cnt = re.findall(find_cnt,link[0]) #抓取超链接里面的数字,即编号
return int(cnt[0])
def get_name(number):
"""
提取小说的书名和作者
:param number: 小说编号
:return: 书名和作者
"""
url = 'http://www.zxcs.me/post/'
novel_url = url+str(number)
html = ask_url(novel_url)
soup = BeautifulSoup(html,'lxml')
title = str(soup.select('#content > h1 ')[0]) #小说的名字啊的信息
find_name = re.compile(r'《(.*)》') # 提取书名,即<<>>之间的内容
name = re.findall(find_name,title)[0]
find_author = re.compile(r':(.+?)<')
author = re.findall(find_author,title)[0] #提取作者
return name,author
def get_rank(number):
"""
获取小说的评价(投票的结果)
:param number:
:return: 投票的结果
"""
voteurl = 'http://www.zxcs.me/content/plugins/cgz_xinqing/cgz_xinqing_action.php?action=show&id={}'.format(number)
vote_html = requests.get(voteurl, headers=head)
data1 = vote_html.text
data_split = data1.split(",")
# print(data_split)
rank_data = []
for item in data_split:
rank = int(item)
rank_data.append(rank)
return rank_data
def ask_url(url):
request = urllib.request.Request(url, headers=head)
html=""
try:
response=urllib.request.urlopen(request)
html=response.read().decode("utf-8")
# print(html)
except urllib.error.URLError as e:
if hasattr(e,"code"):
print(e.code)
if hasattr(e,"reason"):
print(e.reason)
return html
def dealData (start,number):
"""
抓取网页的数据
:param start: 开始的小说标号
:param number: 最后的小说标号
:return: 结果的列表
"""
result = []
for i in range(start,number):
data=[]
try:
title ,author = get_name(i)
rank = get_rank(i)
data=[i,title,author]+rank
result.append(data)
print(i)
time.sleep(1)
except:
continue
return result
def write2Csv(datalist):
cols=['序列','作者','仙草','粮草' ,'干草', '枯草', '毒草']
df = pd.DataFrame(datalist,columns=cols)
df.to_csv("zxcs.csv")
def write2X(datalist) :
workbook = xlwt.Workbook(encoding="utf-8")
worksheet = workbook.add_sheet('sheet1', cell_overwrite_ok=True)
col = ("序列", "书名", "作者", "仙草", "粮草", "干草", "枯草", "毒草")
for i in range(0, 8):
worksheet.write(0, i, col[i])
for i in range(len(datalist)):
for j in range(0, 8):
worksheet.write(i+1, j, datalist[j])
# savepath1 = ".\\book.xls"
workbook.save("zxcs.xls")
if __name__ == '__main__':
main()
我是个初学者,现在只是实现了这个功能,可以优化的地方还很多,我会继续学习的…
附一个知轩藏书书籍的排名(按仙草3分,粮草1分,枯草-1分,毒草-3分算)