Python爬虫练习——文泉书籍信息获取[失效]
本帖最后由 ligxi 于 2020-9-12 19:46 编辑最近看到论坛的大佬写了很多文泉的爬虫工具,奈何本人能力有限写不出那么高级的爬虫,所以退求其次写个书籍基础信息获取的爬虫吧!
更新:
0.0.3版
新增书籍地址。
0.0.2版
1、加入Cookie是否有效的提示。
2、加入起始页,现在可以指定开始页。
3、修复小bug。
此代码会获取以下信息,有能力的可自行修改参数添加更多信息:
注意事项:
1、有些模块是第一次使用,可能存在一些bug,请见谅!
2、网站API端口可能随时会改,所以此代码可能也会随时失效。{:1_923:}
3、网站目前加强了各种防御,cookie每隔一段时间就会失效,需要重新登录获取,最后在源代码中更改"Cookie"后面的值即可。
4、在代码中加入请求的间隔时间,过快的请求很可能会被服务器拉黑一段时间。可自行修改源代码中的time.sleep()时间,单位为s,比如time.sleep(0.5)或time.sleep(2)都可以。
Cookie获取方式:
登录文泉账号后,在浏览器调出控制台,然后输入document.cookie即可获取,最后复制包括引号的所有Cookie信息。
最后送给大家一份刚获取的有关Python书籍的数据:lol
Python书籍信息:
https://www.lanzouj.com/i94zcni
源码:
https://www.lanzouj.com/i97pl9g
需要安装的第三方库:
pip install python-docx
pip install requests
代码示例:
# -*- coding: utf-8 -*-
import urllib.parse
import string
import requests
import json
import re
import time
import os
import sys
# doc文档模块
from docx import Document
from docx.shared import Inches
from docx.oxml.ns import qn
# cookie修改
Cookie = 'PHPSESSID=5s6umsm3ic7hmp9djhkia854s9; _gid=398749400617; _gidv=9e54db532452f68408485a0f3f20a1b1'
# 接收用户输入的关键字
flag = True
keyword = ''
while flag:
keyword = input('请输入搜索的关键字:')
if keyword:
flag = False
else:
print('关键字为空,请重新输入!')
# 要发送的请求
wqxuetang_url = r'https://lib-nuanxin.wqxuetang.com/v1/search/initsearch'
# 字符转码
new_wqxuetang_url = urllib.parse.quote(wqxuetang_url, safe=string.printable)
# 发送请求
def get_response(page=1):
# 请求头
headers = {
'Accept': 'application/json, text/plain, */*',
'Accept - Encoding': 'gzip, deflate, br',
'Accept-Language': 'zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2',
'Connection': 'keep-alive',
'Host': 'lib-nuanxin.wqxuetang.com',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:72.0) Gecko/20100101 Firefox/72.0',
'Cookie': Cookie
}
# 要发送的数据
data = {
'kw': keyword,
'type': 1,
'begindate': '',
'enddate': '',
'tid': '',
'libclass': '',
'cnclass': '',
'tag': '',
'author': '',
'pn': page,
'size': 10,
'isfquery': 'undefined',
'sort': 1
}
# 发送请求,带数据和请求头
response = requests.post(url=new_wqxuetang_url, data=data, headers=headers)
# 转为JSON对象
dict_str = json.loads(response.text)
return dict_str
# 保存数据
def data_download(dict_str):
global count
# 匹配网页标签并替换
rec = re.compile('</?+\s?\d?/?>')
# 写入文件
for item in dict_str['data']['list']:
# 分割线
data1 = '{0}【华丽的分割线】{0}\n'.format('*' * 30)
f1.write(data1)
# 书ID号
data2 = '书的ID号:%s\n' % item['numid']
f1.write(data2)
print('BID:%s\t' % item['numid'], end='')
# 书名
book_name = item['name']
result = set(re.findall(rec, book_name))
for ret in result:
book_name = book_name.replace(ret, '')
data3 = '书名:《%s》\n' % book_name
f1.write(data3)
print('书名:《%s》\t' % book_name, end='')
# 作者
data4 = '作者:%s\n' % item['author']
f1.write(data4)
# 出版时间
data5 = '出版时间:%s\n' % item['pubdate']
f1.write(data5)
print('出版时间:%s' % item['pubdate'])
# 出版社
data6 = '出版社:%s\n' % item['pub']
f1.write(data6)
# 图书简介
des = item['descript']
result = set(re.findall(rec, des))
for ret in result:
des = des.replace(ret, '')
data7 = '图书简介 :%s\n' % des
f1.write(data7)
data8 = '书籍地址:https://lib-nuanxin.wqxuetang.com/#/Book/%s\n\n' % item['numid']
f1.write(data8)
# 刷新缓存区
f1.flush()
# 图片请求头
img_headers = {
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',
'Accept - Encoding': 'gzip, deflate, br',
'Accept-Language': 'zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2',
'Connection': 'keep-alive',
'Host': 'bookask-cover.oss-cn-beijing.aliyuncs.com',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:72.0) Gecko/20100101 Firefox/72.0',
'Cookie': Cookie
}
# 拿到图片的请求地址
img_url = item['coverurl']
# 发送请求
img_data = requests.get(url=img_url, headers=img_headers)
# 发送间隔
time.sleep(2)
# 把图片写入本地目录
img_count = '%s\\%s.jpg' % (pt, count)
with open(img_count, 'wb') as fp:
fp.write(img_data.content)
# 把书籍信息写入doc
data1 = data1.replace('\n', '')
myDocument.add_paragraph(data1)
# 向文档里添加图片
myDocument.add_picture(img_count, width=Inches(2), height=Inches(3))
# 处理文字
datas =
datas = map(lambda text: text.replace('\n', ''), datas)
for data_item in datas:
myDocument.add_paragraph(u'%s' % data_item)
#
myDocument.add_paragraph()
# 指数加1
count += 1
# 图片计数
count = 1
# 第一次发送数据
dict_str = get_response()
# 判断cookie是否失效
login = dict_str['errmsg']
if login == '请先登录':
input('cookie已失效,请重新获取登录后的cookie进行替换,本程序自动结束!')
sys.exit()
# 取最大页数
page_count = dict_str['data']['pageinfo']['pagecount']
print('约%s页' % page_count)
# 获取开始页数
flag1 = True
mincount = 1
while flag1:
min_page = input('请输入要开始获取的页数,默认值为第1页:')
if min_page.isdigit():
mincount = int(min_page)
flag1 = False
elif min_page == '':
flag1 = False
else:
print('非法参数!请重新输入')
# 获取最大页数
flag2 = True
while flag2:
max_page = input('请输入要获取的总页数,默认值为最大页数:')
if max_page.isdigit():
page_count = int(max_page)
flag2 = False
elif max_page == '':
flag2 = False
else:
print('非法参数!请重新输入')
# 获取当前工作目录
root = os.getcwd()
# 拼接路径
pt = os.path.join(root, keyword)
# 如果目录不存在则创建文件夹
if not os.path.isdir(pt):
os.mkdir(root + '\\%s' % keyword)
# 创建空白文档,并设置样式
myDocument = Document()
myDocument.styles['Normal'].font.name = u'微软雅黑'
myDocument.styles['Normal']._element.rPr.rFonts.set(qn('w:eastAsia'), u'微软雅黑')
# 创建空白文件,并设置编码
f1 = open('%s.txt' % keyword, 'w', encoding='utf-8')
# 获取数据
for page in range(mincount, page_count + 1):
print('第%s页书籍信息:' % page)
# 发送请求
dict_str = get_response(page)
# 如果为空则结束发送
if not dict_str['data']['list']:
break
# 把数据写入文件
data_download(dict_str)
# 提示信息
print('【第%s页数据写入文件中...】' % page)
# 延迟发送请求
time.sleep(5)
#
# 保存文件并关闭
f1.close()
myDocument.save('%s.doc' % keyword)
print('数据写入完毕!本程序自动结束!')
ligxi 发表于 2020-2-7 18:11
把你改的源码发个我看看
我没改呀,只加了两行注释
# -*- coding: utf-8 -*-
#by 52 ligxi
import urllib.parse
import string
import requests
import json
import re
import time
import os
# doc文档模块
from docx import Document # 需要pip install python-docx,pip uninstall docx卸载
from docx.shared import Inches
from docx.oxml.ns import qn
# 接收用户输入的关键字
flag1 = True
keyword = ''
while flag1:
keyword = input('请输入搜索的关键字:')
if keyword:
flag1 = False
else:
print('关键字为空,请重新输入!')
# 要发送的请求
wqxuetang_url = r'https://lib-nuanxin.wqxuetang.com/v1/search/initsearch'
# 字符转码
new_wqxuetang_url = urllib.parse.quote(wqxuetang_url, safe=string.printable)
# 发送请求
def get_response(page=1):
# 请求头
#
# Cookie获取方式:
# 在浏览器调出控制台,然后输入document.cookie即可获取。
headers = {
'Accept': 'application/json, text/plain, */*',
'Accept - Encoding': 'gzip, deflate, br',
'Accept-Language': 'zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2',
'Connection': 'keep-alive',
'Host': 'lib-nuanxin.wqxuetang.com',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:72.0) Gecko/20100101 Firefox/72.0',
'Cookie': "_gid=387202506456; _gidv=a6d0c40a2586c69ee3fdc1db569c5ded; ssxmod_itna=WuD=BK7K4lfG77XxDv5DKG=OGQ0OInqitbDl=2DA5D8D6DQeGTQUPWHQCHCwNWoQ=Bb4ow9hS4tTzUCxcm5IzId4GLDmKDyb0hxPKD4bKGwD0eG+DD4DWmx03DoxGABhaTKiODQ40kDmqG2RqNDA4DjWkmhWktj/dXDxGUeIMh5WqDMD7tD/8GtXi=DGuTiXDGWQhj/SqGuDG=4wTLDx0P13GE47YvCbi3GuA+4KgG54hwqGDYeKEm5bio3UhqmpAHjXDDA0Y+feD===; ssxmod_itna2=WuD=BK7K4lfG77XxDv5DKG=OGQ0OInqitD6aIi40y…"
}
# 要发送的数据
data = {
'kw': keyword,
'type': 1,
'begindate': '',
'enddate': '',
'tid': '',
'libclass': '',
'cnclass': '',
'tag': '',
'author': '',
'pn': page,
'size': 10,
'isfquery': 'undefined',
'sort': 1
}
# 发送请求,带数据和请求头
response = requests.post(url=new_wqxuetang_url, data=data, headers=headers)
# 转为JSON对象
dict_str = json.loads(response.text)
return dict_str
# 保存数据
def data_download(dict_str):
global count
# 匹配网页标签并替换
rec = re.compile('</?+\s?\d?/?>')
# 写入文件
for item in dict_str['data']['list']:
# 分割线
data1 = '{0}【华丽的分割线】{0}\n'.format('*' * 30)
f1.write(data1)
# 书ID号
data2 = '书的ID号:%s\n' % item['numid']
f1.write(data2)
print('BID:%s\t' % item['numid'], end='')
# 书名
book_name = item['name']
result = set(re.findall(rec, book_name))
for ret in result:
book_name = book_name.replace(ret, '')
data3 = '书名:《%s》\n' % book_name
f1.write(data3)
print('书名:《%s》' % book_name)
# 作者
data4 = '作者:%s\n' % item['author']
f1.write(data4)
# 出版时间
data5 = '出版时间:%s\n' % item['pubdate']
f1.write(data5)
# 出版社
data6 = '出版社:%s\n' % item['pub']
f1.write(data6)
# 图书简介
des = item['descript']
result = set(re.findall(rec, des))
for ret in result:
des = des.replace(ret, '')
data7 = '图书简介 :%s\n\n' % des
f1.write(data7)
# 刷新缓存区
f1.flush()
# 图片请求头
img_headers = {
'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8',
'Accept - Encoding': 'gzip, deflate, br',
'Accept-Language': 'zh-CN,zh;q=0.8,zh-TW;q=0.7,zh-HK;q=0.5,en-US;q=0.3,en;q=0.2',
'Connection': 'keep-alive',
'Host': 'bookask-cover.oss-cn-beijing.aliyuncs.com',
'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:72.0) Gecko/20100101 Firefox/72.0',
'Cookie': "_gid=387202506456; _gidv=a6d0c40a2586c69ee3fdc1db569c5ded; ssxmod_itna=WuD=BK7K4lfG77XxDv5DKG=OGQ0OInqitbDl=2DA5D8D6DQeGTQUPWHQCHCwNWoQ=Bb4ow9hS4tTzUCxcm5IzId4GLDmKDyb0hxPKD4bKGwD0eG+DD4DWmx03DoxGABhaTKiODQ40kDmqG2RqNDA4DjWkmhWktj/dXDxGUeIMh5WqDMD7tD/8GtXi=DGuTiXDGWQhj/SqGuDG=4wTLDx0P13GE47YvCbi3GuA+4KgG54hwqGDYeKEm5bio3UhqmpAHjXDDA0Y+feD===; ssxmod_itna2=WuD=BK7K4lfG77XxDv5DKG=OGQ0OInqitD6aIi40y…"
}
# 拿到图片的请求地址
img_url = item['coverurl']
# 发送请求
img_data = requests.get(url=img_url, headers=img_headers)
# 发送间隔
time.sleep(1)
# 把图片写入本地目录
img_count = '%s\\%s.jpg' % (pt, count)
with open(img_count, 'wb') as fp:
fp.write(img_data.content)
# 把书籍信息写入doc
data1 = data1.replace('\n', '')
myDocument.add_paragraph(data1)
# 向文档里添加图片
myDocument.add_picture(img_count, width=Inches(2), height=Inches(3))
# 处理文字
datas =
datas = map(lambda text: text.replace('\n', ''), datas)
for data_item in datas:
myDocument.add_paragraph(data_item)
#
myDocument.add_paragraph()
# 指数加1
count += 1
# 图片计数
count = 1
# 第一次发送数据
dict_str = get_response()
# 取最大页数
page_count = dict_str['data']['pageinfo']['pagecount']
print('约%s页' % page_count)
# 获取页数
flag2 = True
max_page = ''
while flag2:
max_page = input('请输入要获取的总页数,默认值为最大,从第1页开始到:')
if max_page.isdigit() or max_page == '':
flag2 = False
else:
print('非法参数!请重新输入')
# 判断要获取的最大页数
if max_page == '':
max_page = page_count
#
max_page = int(max_page)
# 获取当前工作目录
root = os.getcwd()
# 拼接路径
pt = os.path.join(root, keyword)
# 如果目录不存在则创建文件夹
if not os.path.isdir(pt):
os.mkdir(root + '\\%s' % keyword)
# 创建空白文档,并设置样式
myDocument = Document()
myDocument.styles['Normal'].font.name = u'微软雅黑'
myDocument.styles['Normal']._element.rPr.rFonts.set(qn('w:eastAsia'), u'微软雅黑')
# 创建空白文件,并设置编码
f1 = open('%s.txt' % keyword, 'w', encoding='utf-8')
# 获取数据
for page in range(1, max_page + 1):
print('第%s页书籍信息:' % page)
# 发送请求
dict_str = get_response(page)
# 如果为空则结束发送
if not dict_str['data']['list']:
break
# 把数据写入文件
data_download(dict_str)
# 提示信息
print('【第%s页数据写入文件中...】' % page)
# 延迟发送请求
time.sleep(3)
#
# 保存文件并关闭
f1.close()
myDocument.save('%s.doc' % keyword)
print('数据写入完毕!本程序自动结束!')
你好,从特定页开始下载后,下载了25个图片目录后,便会出现这个错误,请您查看一下,谢谢了,。
Traceback (most recent call last):
File "D:\获取书籍信息\wqxuetang_books-2.py", line 219, in <module>
data_download(dict_str)
File "D:\获取书籍信息\wqxuetang_books-2.py", line 142, in data_download
myDocument.add_paragraph(data_item)
File "C:\Users\Administrator\AppData\Local\Programs\Python\Python36\lib\site-packages\docx\document.py", line 56, in add_paragraph
return self._body.add_paragraph(text, style)
File "C:\Users\Administrator\AppData\Local\Programs\Python\Python36\lib\site-packages\docx\blkcntnr.py", line 37, in add_paragraph
paragraph.add_run(text)
File "C:\Users\Administrator\AppData\Local\Programs\Python\Python36\lib\site-packages\docx\text\paragraph.py", line 37, in add_run
run.text = text
File "C:\Users\Administrator\AppData\Local\Programs\Python\Python36\lib\site-packages\docx\text\run.py", line 163, in text
self._r.text = text
File "C:\Users\Administrator\AppData\Local\Programs\Python\Python36\lib\site-packages\docx\oxml\text\run.py", line 104, in text
_RunContentAppender.append_to_run_from_text(self, text)
File "C:\Users\Administrator\AppData\Local\Programs\Python\Python36\lib\site-packages\docx\oxml\text\run.py", line 134, in append_to_run_from_text
appender.add_text(text)
File "C:\Users\Administrator\AppData\Local\Programs\Python\Python36\lib\site-packages\docx\oxml\text\run.py", line 143, in add_text
self.flush()
File "C:\Users\Administrator\AppData\Local\Programs\Python\Python36\lib\site-packages\docx\oxml\text\run.py", line 165, in flush
self._r.add_t(text)
File "C:\Users\Administrator\AppData\Local\Programs\Python\Python36\lib\site-packages\docx\oxml\text\run.py", line 41, in add_t
t = self._add_t(text=text)
File "C:\Users\Administrator\AppData\Local\Programs\Python\Python36\lib\site-packages\docx\oxml\xmlchemy.py", line 273, in _add_child
setattr(child, key, value)
File "src\lxml\etree.pyx", line 1024, in lxml.etree._Element.text.__set__
File "src\lxml\apihelpers.pxi", line 747, in lxml.etree._setNodeText
File "src\lxml\apihelpers.pxi", line 735, in lxml.etree._createTextNode
File "src\lxml\apihelpers.pxi", line 1540, in lxml.etree._utf8
ValueError: All strings must be XML compatible: Unicode or ASCII, no NULL bytes or control characters 沙发!!!!!1 litengdada 发表于 2020-2-7 16:03
沙发!!!!!1
{:301_997:}学习学习! 学习了虽然不懂
感谢分享谢谢 没有书的内容啊,简介没用的 策士 发表于 2020-2-7 16:37
没有书的内容啊,简介没用的
本来就不是获取书内容的,只是提供id和书的基础信息而已。书的内容都是图片,可以用论坛大佬的写的工具下载。{:301_1007:} 进来学习,不错的工具,有大用处,不明白的就算了 ymhld 发表于 2020-2-7 17:24
进来学习,不错的工具,有大用处,不明白的就算了
现在防得太厉害,很难批量下载了,等大佬更新下载工具后方便找书,不用去翻。{:301_973:} ligxi 发表于 2020-2-7 17:40
现在防得太厉害,很难批量下载了,等大佬更新下载工具后方便找书,不用去翻。
有些模块安不上,
from exceptions import PendingDeprecationWarning
ModuleNotFoundError: No module named 'exceptions' ymhld 发表于 2020-2-7 17:51
有些模块安不上,
from exceptions import PendingDeprecationWarning
ModuleNotFoundError: No mo ...
这不是我用的模块吧{:301_1009:},看了一下好像是Python3.8的内置模块吧?