吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 8714|回复: 55
收起左侧

[Python 转载] Python爬虫练习——文泉书籍信息获取[失效]

[复制链接]
ligxi 发表于 2020-2-7 16:02
本帖最后由 ligxi 于 2020-9-12 19:46 编辑

最近看到论坛的大佬写了很多文泉的爬虫工具,奈何本人能力有限写不出那么高级的爬虫,所以退求其次写个书籍基础信息获取的爬虫吧!

更新:
0.0.3版
新增书籍地址。

0.0.2版
1、加入Cookie是否有效的提示。
2、加入起始页,现在可以指定开始页。
3、修复小bug。

此代码会获取以下信息,有能力的可自行修改参数添加更多信息:
搜狗截图20200207161224.png

注意事项:
1、有些模块是第一次使用,可能存在一些bug,请见谅!
2、网站API端口可能随时会改,所以此代码可能也会随时失效。
3、网站目前加强了各种防御,cookie每隔一段时间就会失效,需要重新登录获取,最后在源代码中更改"Cookie"后面的值即可。
4、在代码中加入请求的间隔时间,过快的请求很可能会被服务器拉黑一段时间。可自行修改源代码中的time.sleep()时间,单位为s,比如time.sleep(0.5)或time.sleep(2)都可以。

Cookie获取方式:
登录文泉账号后,在浏览器调出控制台,然后输入document.cookie即可获取,最后复制包括引号的所有Cookie信息。
搜狗截图20200207155818.png

最后送给大家一份刚获取的有关Python书籍的数据
Python书籍信息:
https://www.lanzouj.com/i94zcni
源码:
https://www.lanzouj.com/i97pl9g

需要安装的第三方库:
pip install python-docx
pip install requests

代码示例:
[Python] 纯文本查看 复制代码
# -*- 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('</?[a-zA-Z]+\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 = '书籍地址:[url=https://lib-nuanxin.wqxuetang.com/#/Book/%s]https://lib-nuanxin.wqxuetang.com/#/Book/%s[/url]\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 = [data2, data3, data4, data5, data6, data7, data8]
        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('数据写入完毕!本程序自动结束!')

免费评分

参与人数 4吾爱币 +6 热心值 +4 收起 理由
itachi3 + 1 + 1 热心回复!
wtujcf123 + 1 + 1 谢谢@Thanks!要是能加上从特定页开始就更完美了。
苏紫方璇 + 3 + 1 感谢发布原创作品,吾爱破解论坛因你更精彩!
ymhld + 1 + 1 我很赞同!好东西,原来是闷头写这个呢。

查看全部评分

本帖被以下淘专辑推荐:

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

ymhld 发表于 2020-2-7 18:13
ligxi 发表于 2020-2-7 18:11
把你改的源码发个我看看

我没改呀,只加了两行注释

[Python] 纯文本查看 复制代码
# -*- 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('</?[a-zA-Z]+\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 = [data2, data3, data4, data5, data6, data7]
        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('数据写入完毕!本程序自动结束!')
wtujcf123 发表于 2020-2-8 13:12
你好,从特定页开始下载后,下载了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
litengdada 发表于 2020-2-7 16:03
 楼主| ligxi 发表于 2020-2-7 16:08

学习学习!

免费评分

参与人数 1吾爱币 +1 热心值 +1 收起 理由
ymhld + 1 + 1 热心回复!

查看全部评分

cdwdz 发表于 2020-2-7 16:15
学习了  虽然不懂
感谢分享  谢谢
策士 发表于 2020-2-7 16:37
没有书的内容啊,简介没用的
 楼主| ligxi 发表于 2020-2-7 16:40
策士 发表于 2020-2-7 16:37
没有书的内容啊,简介没用的

本来就不是获取书内容的,只是提供id和书的基础信息而已。书的内容都是图片,可以用论坛大佬的写的工具下载。

免费评分

参与人数 1吾爱币 +1 热心值 +1 收起 理由
ymhld + 1 + 1 热心回复!

查看全部评分

ymhld 发表于 2020-2-7 17:24
进来学习,不错的工具,有大用处,不明白的就算了
 楼主| ligxi 发表于 2020-2-7 17:40
ymhld 发表于 2020-2-7 17:24
进来学习,不错的工具,有大用处,不明白的就算了

现在防得太厉害,很难批量下载了,等大佬更新下载工具后方便找书,不用去翻。
ymhld 发表于 2020-2-7 17:51
ligxi 发表于 2020-2-7 17:40
现在防得太厉害,很难批量下载了,等大佬更新下载工具后方便找书,不用去翻。

有些模块安不上,
    from exceptions import PendingDeprecationWarning
ModuleNotFoundError: No module named 'exceptions'
 楼主| ligxi 发表于 2020-2-7 17:54
ymhld 发表于 2020-2-7 17:51
有些模块安不上,
    from exceptions import PendingDeprecationWarning
ModuleNotFoundError: No mo ...

这不是我用的模块吧,看了一下好像是Python3.8的内置模块吧?
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

GMT+8, 2025-1-14 19:17

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

快速回复 返回顶部 返回列表