166818008 发表于 2022-4-1 17:46

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

本帖最后由 166818008 于 2022-4-1 17:49 编辑

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

# -*- 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)
            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)
            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').string.strip()
                people_num = get_people_num(book_url)
                people_num = people_num.strip('人评价')
            except:
                people_num = '0'

            book_list.append()
            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)
      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').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, 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.decode()))# utf8->unicode
    for i in range(len(book_tag_lists)):
      ws.append(['序号', '书名', '评分', '评价人数', '作者', '出版社'])
      count = 1
      for bl in book_lists:
            ws.append(, float(bl), int(bl), bl, bl])
            count += 1
    save_path = 'book_list'
    for i in range(len(book_tag_lists)):
      save_path += ('-' + book_tag_lists.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) 再试试看哪 ...

在发贴求助前,其实已经没有报错,可以运行,但一直处在下载状态

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
一直在运行状态是因为你的要的分类太多,而且每个分类都得要跑完,每个分类的页数也是非常的多

大佬,昨天我运行了五六个小时,程序一直运行在那里,就是不出结果啊
能帮忙运行看看哪里出问题了吗?
页: [1]
查看完整版本: 求大佬帮助修改完善“豆拌”爬虫代码