吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 996|回复: 9
收起左侧

[讨论] 求大佬帮助修改完善“豆拌”爬虫代码

[复制链接]
166818008 发表于 2022-4-1 17:46
本帖最后由 166818008 于 2022-4-1 17:49 编辑

代码是从“世界最大同性交友网”获取的,功能是爬取“豆拌”上的图书信息。源码我认为可能是用早期python3版本编写的,我在源码基础上进行修改完善,但仍有一些问题。
但我个人能力有限,不知哪里还需修改,求懂资深大佬帮助修改完善。

[Python] 纯文本查看 复制代码
# -*- coding: UTF-8 -*-

# import sys
import time
import urllib
from urllib import parse
import urllib.error
# from importlib import reload

import urllib.request
import numpy as np
from bs4 import BeautifulSoup
from openpyxl import Workbook

# reload(sys)
# sys.setdefaultencoding('utf8')


# Some User Agents
hds = [{'User-Agent': 'Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.6) Gecko/20091201 Firefox/3.5.6'},
       {'User-Agent': 'Mozilla/5.0 (Windows NT 6.2) AppleWebKit/535.11 (KHTML, like Gecko) Chrome/17.0.963.12 '
                      'Safari/535.11'},
       {'User-Agent': 'Mozilla/5.0 (compatible; MSIE 10.0; Windows NT 6.2; Trident/6.0)'}]


def book_spider(book_tag):
    page_num = 0
    book_list = []
    try_times = 0

    while 1:
        # url='http://www.douban.com/tag/%E5%B0%8F%E8%AF%B4/book?start=0' # For Test
        # url='http://www.douban.com/tag/'+urllib.quote(book_tag)+'/book?start='+str(page_num*15)
        # url = 'https://www.douban.com/tag/' + urllib.parse.quote(book_tag) + '/book?start=' + str(page_num * 15)
        # time.sleep(np.random.rand() * 5)
        url = 'https://www.douban.com/tag/' + urllib.parse.quote(book_tag) + '/book?start=' + str(page_num * 15)
        time.sleep(np.random.rand() * 5)

        # Last Version
        try:
            req = urllib.request.Request(url, headers=hds[page_num % len(hds)])
            source_code = urllib.request.urlopen(req).read()
            plain_text = str(source_code)
        # except (urllib.request.HTTPError, urllib.request.URLError) as e:
        except (urllib.error.HTTPError, urllib.error.URLError) as e:
            print(e)
            continue

        # Previous Version, IP is easy to be Forbidden
        # source_code = requests.get(url)
        # plain_text = source_code.text

        soup = BeautifulSoup(plain_text, "html.parser")
        list_soup = soup.find('div', {'class': 'mod book-list'})

        try_times += 1
        if list_soup is None and try_times < 200:
            continue
        elif list_soup is None or len(list_soup) <= 1:
            break  # Break when no information got after 200 times requesting

        for book_info in list_soup.findAll('dd'):
            title = book_info.find('a', {'class': 'title'}).string.strip()
            desc = book_info.find('div', {'class': 'desc'}).string.strip()
            desc_list = desc.split('/')
            book_url = book_info.find('a', {'class': 'title'}).get('href')

            try:
                author_info = '作者/译者: ' + '/'.join(desc_list[0:-3])
            except:
                author_info = '作者/译者: 暂无'
            try:
                pub_info = '出版信息: ' + '/'.join(desc_list[-3:])
            except:
                pub_info = '出版信息: 暂无'
            try:
                rating = book_info.find('span', {'class': 'rating_nums'}).string.strip()
            except:
                rating = '0.0'
            try:
                # people_num = book_info.findAll('span')[2].string.strip()
                people_num = get_people_num(book_url)
                people_num = people_num.strip('人评价')
            except:
                people_num = '0'

            book_list.append([title, rating, people_num, author_info, pub_info])
            try_times = 0  # set 0 when got valid information
        page_num += 1
        print('Downloading Information From Page %d' % page_num)
    return book_list


def get_people_num(url):
    # url='http://book.douban.com/subject/6082808/?from=tag_all' # For Test
    try:
        req = urllib.request.Request(url, headers=hds[np.random.randint(0, len(hds))])
        source_code = urllib.request.urlopen(req).read()
        plain_text = str(source_code)
    except (urllib.error.HTTPError, urllib.error.URLError) as e:
        print(e)
    soup = BeautifulSoup(plain_text, "html.parser")
    people_num = soup.find('div', {'class': 'rating_sum'}).findAll('span')[1].string.strip()
    return people_num


def do_spider(book_tag_lists):
    book_lists = []
    for book_tag in book_tag_lists:
        book_list = book_spider(book_tag)
        book_list = sorted(book_list, key=lambda x: x[1], reverse=True)
        book_lists.append(book_list)
    return book_lists


def print_book_lists_excel(book_lists, book_tag_lists):
    wb = Workbook(optimized_write=True)
    ws = []
    for i in range(len(book_tag_lists)):
        ws.append(wb.create_sheet(title=book_tag_lists[i].decode()))  # utf8->unicode
    for i in range(len(book_tag_lists)):
        ws[i].append(['序号', '书名', '评分', '评价人数', '作者', '出版社'])
        count = 1
        for bl in book_lists[i]:
            ws[i].append([count, bl[0], float(bl[1]), int(bl[2]), bl[3], bl[4]])
            count += 1
    save_path = 'book_list'
    for i in range(len(book_tag_lists)):
        save_path += ('-' + book_tag_lists[i].decode())
    save_path += '.xlsx'
    wb.save(save_path)


if __name__ == '__main__':
    # book_tag_lists = ['心理','判断与决策','算法','数据结构','经济','历史']
    # book_tag_lists = ['传记','哲学','编程','创业','理财','社会学','佛教']
    # book_tag_lists = ['思想','科技','科学','web','股票','爱情','两性']
    # book_tag_lists = ['计算机','机器学习','linux','android','数据库','互联网']
    # book_tag_lists = ['数学']
    # book_tag_lists = ['摄影','设计','音乐','旅行','教育','成长','情感','育儿','健康','养生']
    # book_tag_lists = ['商业','理财','管理']
    # book_tag_lists = ['名著']
    # book_tag_lists = ['科普','经典','生活','心灵','文学']
    # book_tag_lists = ['科幻','思维','金融']
    book_tag_lists = ['个人管理', '时间管理', '投资', '文化', '宗教']
    book_lists = do_spider(book_tag_lists)
    print_book_lists_excel(book_lists, book_tag_lists)

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

熊猫拍板砖 发表于 2022-4-1 18:27
按照目前来说,你把 wb = Workbook(optimized_write=True) 改成wb = Workbook(write_only=True) 再试试看哪里报错吧
知心 发表于 2022-4-1 19:42
本帖最后由 知心 于 2022-4-1 19:52 编辑

try catch用的太多了,库的话requests应该比现在这个更方便一些。你描述一下最终的要求或者想法。
 楼主| 166818008 发表于 2022-4-1 19:54
熊猫拍板砖 发表于 2022-4-1 18:27
按照目前来说,你把 wb = Workbook(optimized_write=True) 改成wb = Workbook(write_only=True) 再试试看哪 ...

在发贴求助前,其实已经没有报错,可以运行,但一直处在下载状态
image.png
 楼主| 166818008 发表于 2022-4-1 19:59
知心 发表于 2022-4-1 19:42
try catch用的太多了,库的话requests应该比现在这个更方便一些。你描述一下最终的要求或者想法。

1 可以爬下豆瓣读书标签下的所有图书(先测试部分)
2 按评分排名依次存储
3 存储到Excel中,方便筛选搜罗,比如筛选评价人数>1000的高分书籍;可依据不同的主题存储到Excel不同的Sheet
4 采用User Agent伪装为浏览器进行爬取,并加入随机延时来更好的模仿浏览器行为,避免爬虫被封
熊猫拍板砖 发表于 2022-4-1 20:56
166818008 发表于 2022-4-1 19:54
在发贴求助前,其实已经没有报错,可以运行,但一直处在下载状态

一直在运行状态是因为你的要的分类太多,而且每个分类都得要跑完,每个分类的页数也是非常的多
 楼主| 166818008 发表于 2022-4-1 21:13
熊猫拍板砖 发表于 2022-4-1 20:56
一直在运行状态是因为你的要的分类太多,而且每个分类都得要跑完,每个分类的页数也是非常的多

那怎么减少工作量呢,因为我现在只是想测试一下
earlc 发表于 2022-4-1 22:15
缩小分类数量,限制爬取页数之类
 楼主| 166818008 发表于 2022-4-2 12:00
earlc 发表于 2022-4-1 22:15
缩小分类数量,限制爬取页数之类

能帮忙运行一下吗?因为昨天挂了很久,运行到后面他就卡着不动了,一直不出结果
能帮忙看看哪里出问题了吗?
 楼主| 166818008 发表于 2022-4-2 21:53
熊猫拍板砖 发表于 2022-4-1 20:56
一直在运行状态是因为你的要的分类太多,而且每个分类都得要跑完,每个分类的页数也是非常的多

大佬,昨天我运行了五六个小时,程序一直运行在那里,就是不出结果啊
能帮忙运行看看哪里出问题了吗?
您需要登录后才可以回帖 登录 | 注册[Register]

本版积分规则

返回列表

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

GMT+8, 2024-11-25 13:09

Powered by Discuz!

Copyright © 2001-2020, Tencent Cloud.

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