爬虫第四天:爬取我要看的小说

前言:平时看小说都是手机上找个免费软件看的,但是现在的APP要么是只给你几天免费,然后就收钱;要么就是免费但是不断出现广告,忍无可忍!PC端可以找到可以看的免费小说,但是一来必须坐到电脑前不方便,二来总是会自动弹到广告页面,手机浏览器上网看小说也是一样。
所以决定还是自己写个程序把要看的小说爬下来吧~
不多说了,代码如下:

2019年3月27日更新:笔趣阁变更URL了,而且搞了一些http和https之类的变化,导致以前的不能用了,所以更新一下,同时增加了断点续爬的代码,后续计划还要增加代理地址库、分布式爬虫等手段(或者直接用spider等框架?)
2018年11月10日更新:增加了selenium的代码,可以通过输入书名和最近看的章节名字,自动爬取需要的小说章节
注:selenium的使用必须安装相应的浏览器控件,比如我这里用了Chrome,所以首先必须安装Chrome浏览器,然后还要下载版本相应的chromedriver

import requests
from bs4 import BeautifulSoup
import re
import datetime
from selenium import webdriver
import time
import os

#首先通过chrome获得headers,包括user-agent和cookie
headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36',
    'Cookie': '__jsluid=2e1d5b068aad24f7ba11f9a858d4e6e9; jieqiVisitTime=jieqiArticlesearchTime%3D1553649546',
    'Host': 'www.biquyun.com'
}

def get_bookurl(book_name):
    '''通过selenium获得书名对应的链接'''
    browser = webdriver.Chrome()
    url = "http://www.biquyun.com/"
    browser.get(url)
    input = browser.find_element_by_xpath('//*[@id="wd"]') # 点击“搜索栏”
    input.send_keys(book_name)
    button = browser.find_element_by_xpath('//*[@id="sss"]') # 点击“搜索栏”
    button.click()
    time.sleep(1)
    #因为这个网站使用的是弹出新窗口,所以需要跳转到新的页面才能获得url
    windows = browser.current_window_handle
    all_handers = browser.window_handles
    for handle in all_handers:
        if handle != windows:
            browser.switch_to_window(handle)
    time.sleep(1)
    current_url = browser.current_url
    browser.quit()
    print(current_url)
    book_id = re.search('^https://www.biquyun.com/(.*?)/',current_url).group(1)
    print(book_id)
    return book_id

def get_novel(href,book_id):
    '''获得小说的标题和正文'''
    url = r"http://www.biquyun.com/"+book_id+"/"+href+".html"
    r = requests.get(url=url, verify=False)
    r.encoding = 'gbk'
    # time.sleep(1)
    soup = BeautifulSoup(r.text, 'lxml')
    #获取小说的标题
    novel_title = soup.find(name='div',attrs={'class':'bookname'}).h1.text.replace(u'\xa0', u' ').replace(u'\ufffd', u' ')
    # print(novel_title)
    #获取小说的正文
    novel_content = soup.find(name='div',attrs={'id':'content'}).text.replace(u'\xa0', u' ').replace(u'\ufffd', u' ').strip()
    # print(novel_content)
    return novel_title, novel_content

def make_novel(novel_title,novel_content,book_name):
    '''导出小说'''
    with open(book_name+'.txt', 'a', encoding='gbk') as file:
        file.write(novel_title)
        file.write('\r\n')
        file.write(novel_content)
        file.write('\r\n')
        file.write('\r\n')

def get_noveltitle(novel_title):
    '''导出已爬取小说章节的名字,以便后续断点续爬'''
    with open('已爬取小说章节.txt', 'a', encoding='gbk') as file:
        file.write('\n')
        file.write(novel_title)

def get_last_line(filename):
    '''获取文本内的最后一行'''
    try:
        filesize = os.path.getsize(filename)
        if filesize == 0:
            return None
        else:
            with open(filename, 'rb') as fp:  # to use seek from end, must use mode 'rb'
                offset = -50  # initialize offset
                while True:  # offset cannot exceed file size
                    fp.seek(offset, 2)  # read # offset chars from eof(represent by number '2')
                    lines = fp.readlines()  # read from fp to eof
                    if len(lines) >= 2:  # if contains at least 2 lines
                        return lines[-1].decode('gbk')  # then last line is totally included
                    else:
                        offset *= 2  # enlarge offset
    except FileNotFoundError:
        print(filename + ' not found!')
        return None

# print(get_last_line('已爬取小说章节.txt'))

def crawler(last_chapter, n):
    '''爬取小说,支持断点续爬!'''
    if n <= 5:
        n = n + 1
        dd = soup.find(name='a', text=re.compile(last_chapter)).find_all_next(name='dd')
        for i in range(len(dd)):
            href_temp = str(dd[i])
            # print(href_temp)
            href = re.search('^<dd><a href="/.*?/(.*?).html">.*?</a></dd>', href_temp).group(1)
            # print(href)
            try:
                novel_title = str(get_novel(href, book_id)[0]).strip()
                novel_content = get_novel(href, book_id)[1]
                get_noveltitle(novel_title)
                if novel_title.startswith('第'):
                    make_novel(novel_title, novel_content, book_name)
                    print('已爬取小说:《{}》'.format(novel_title))
                else:
                    print('《{}》不是小说正文,已忽略'.format(novel_title))
            except:
                print('第{}次出现错误,开始断点续爬!'.format(n))
                last_chapter = get_last_line('已爬取小说章节.txt')
                print('从《{}》继续开始爬'.format(last_chapter))
                time.sleep(3)
                crawler(last_chapter, n)
    else:
        print('已经迭代5次了,可能被ban ip了,请检查!')
        return None

if __name__=='__main__':
    starttime = datetime.datetime.now()
    book_name = input("请输入书名:")
    last_chapter = input('请输入最近看的一章的名称(如果新书直接回车):')
    book_id = get_bookurl(book_name)
    url = r"https://www.biquyun.com/" + book_id + "/"
    requests.packages.urllib3.disable_warnings()
    r = requests.get(url=url, verify=False)
    r.encoding = 'gbk'
    soup = BeautifulSoup(r.text, 'lxml')
    n = 1
    crawler(last_chapter, n)
    endtime = datetime.datetime.now()
    total_time = (endtime - starttime).seconds
    print("小说爬取完毕,总共耗时{}秒".format(total_time))

下完后是一个txt文件,导入到手机比较好的阅读类APP中即可!

你好!对于爬取菜谱网站,你可以使用 Python 的 requests 和 BeautifulSoup 库来实现。首先,你需要发送请求获取网页的 HTML 内容,然后使用 BeautifulSoup 解析该内容,提取出你所需的菜谱信息。 以下是一个简单的示例代码,以爬取美食天下网站(www.meishij.net)为例: ```python import requests from bs4 import BeautifulSoup def get_recipe(url): response = requests.get(url) soup = BeautifulSoup(response.text, 'html.parser') # 在这里根据网页结构提取菜谱信息 # 例如,获取菜名和食材 recipe_name = soup.find('h1', class_='recipe-title').text.strip() ingredients = soup.find('div', class_='particulars').ul.find_all('li') ingredient_list = [] for ingredient in ingredients: ingredient_list.append(ingredient.text.strip()) # 输出菜谱名称和食材列表 print("菜谱名称:", recipe_name) print("食材列表:", ingredient_list) # 菜谱详情页的URL recipe_url = 'https://www.meishij.net/1' get_recipe(recipe_url) ``` 对于爬取豆瓣 Top250 电影榜单,同样可以使用 requests 和 BeautifulSoup 库来实现。以下是一个简单的示例代码: ```python import requests from bs4 import BeautifulSoup def get_top250(): url = 'https://movie.douban.com/top250' response = requests.get(url) soup = BeautifulSoup(response.text, 'html.parser') movie_list = soup.find('ol', class_='grid_view').find_all('li') for movie in movie_list: # 获取电影排名、名称和评分 rank = movie.find('em').text title = movie.find('span', class_='title').text rating = movie.find('span', class_='rating_num').text # 输出电影信息 print("排名:", rank) print("名称:", title) print("评分:", rating) print() get_top250() ``` 以上代码只是一个简单示例,你可以根据具体的网页结构和需求进行相应的修改和扩展。希望能对你有所帮助!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值