Python爬虫|爬取小说|为什么爬取不出来


import json
import re

import requests
import os
import sys
import traceback
sys.tracebacklimit=0
url='https://www.qb5200.la/book/116524/'
ajax_url='https://pagead2.googlesyndication.com/getconfig/sodar?sv=200&tid=gda&tv=r20230718&st=env'
headers={
':authority: pagead2.googlesyndication.com',
':method: GET',
':path: /getconfig/sodar?sv=200&tid=gda&tv=r20230718&st=env',
':scheme: https',
'accept: */*',
'accept-encoding: gzip, deflate, br',
'accept-language: zh-CN,zh;q=0.9',
'origin: https://www.qb5200.la',
'referer: https://www.qb5200.la/',
'sec-ch-ua: ";Not A Brand";v="99", "Chromium";v="94"',
'sec-ch-ua-mobile: ?0',
'sec-ch-ua-platform: "Windows"',
'sec-fetch-dest: empt',
'sec-fetch-mode: cors',
'sec-fetch-site: cross-site',
'user-agent: Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.71 Safari/537.36',
}
start_url=requests.get(url,headers=headers).content.decode('gbk','ignore')
ajax_urlz=requests.get(ajax_url,headers=headers).content.decode('gbk','ignore')

def get_toc(html):

      toc_url_list=[]
      toc_block=re.findall('<dl class="zjlist>(.*?)</dl>',html,re.S)[0]
      toc_url=re.findall('href="(.*?)"',toc_block,re.S)
      for url in toc_url:
         toc_url_list.append(start_url+url)
         return toc_url_list
def get_article(html):
     chapter_name=re.search('<div class="border">(.*?)</div>',html,re.S).group(1)
     chapter_namez=chapter_name.select('h1:nth-of-type(1)')
     text_block=re.search('<div id="content">(.*?)</div>',html,re.S).group(1)
     text_block=text_block.replace('<br>','')
     return chapter_namez,text_block
def save(chapter_namez,text_block):
     os.makedirs('星门',exist_ok=True)
     with open(os.path.join('星门',chapter_namez+'.txt'),'w',encoding='gbk')as f:
         f.write(text_block)

img

img


修改后还是爬不出来

import json
import re
import requests
import os
import sys
import traceback

sys.tracebacklimit = 0

url = 'https://www.qb5200.la/book/116524/'
ajax_url = 'https://pagead2.googlesyndication.com/getconfig/sodar?sv=200&tid=gda&tv=r20230718&st=env'

headers = {
    'authority': 'pagead2.googlesyndication.com',
    'method': 'GET',
    'path': '/getconfig/sodar?sv=200&tid=gda&tv=r20230718&st=env',
    'scheme': 'https',
    'accept': '*/*',
    'accept-encoding': 'gzip, deflate, br',
    'accept-language': 'zh-CN,zh;q=0.9',
    'origin': 'https://www.qb5200.la',
    'referer': 'https://www.qb5200.la/',
    'sec-ch-ua': '";Not A Brand";v="99", "Chromium";v="94"',
    'sec-ch-ua-mobile': '?0',
    'sec-ch-ua-platform': '"Windows"',
    'sec-fetch-dest': 'empty',
    'sec-fetch-mode': 'cors',
    'sec-fetch-site': 'cross-site',
    'user-agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.71 Safari/537.36',
}

start_url = requests.get(url, headers=headers).content.decode('gbk', 'ignore')
ajax_urlz = requests.get(ajax_url, headers=headers).content.decode('gbk', 'ignore')


def get_toc(html):
    toc_url_list = []
    toc_block = re.findall('<dl class="zjlist>(.*?)</dl>', html, re.S)[0]
    toc_url = re.findall('href="(.*?)"', toc_block, re.S)
    for url in toc_url:
        toc_url_list.append(start_url + url)
    return toc_url_list


def get_article(html):
    chapter_name = re.search('<div class="border">(.*?)</div>', html, re.S).group(1)
    chapter_name = chapter_name.select('h1:nth-of-type(1)')
    text_block = re.search('<div id="content">(.*?)</div>', html, re.S).group(1)
    text_block = text_block.replace('<br>', '')
    return chapter_name, text_block


def save(chapter_namez, text_block):
    os.makedirs('星门', exist_ok=True)
    i = 0;
    while i < 627 in chapter_namez:
        i += 1;
        chapter_name = chapter_namez[i]
        if chapter_name:
            break
        else:
            'Unknown_Chapter_Name'
    with open(os.path.join('星门', chapter_namez + '.txt'), 'w', encoding='gbk') as f:
        f.write(text_block)


爬虫用xpath,比re好使

import requests
from lxml import etree

url='https://www.qb5200.la/book/116524/'
headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36'}

res=requests.get(url,headers=headers)
html=etree.HTML(res.text)
chapter_name=html.xpath("//*/dl[@class='zjlist']/dd//text()")
href=html.xpath("//*/dl[@class='zjlist']/dd/a/@href")
base_url="https://www.qb5200.la/book/116524/"
for i in range(len(chapter_name)):
    print(chapter_name[i],base_url+href[i])
    data=requests.get(base_url+href[i],headers=headers)
    html=etree.HTML(data.text)
    content=html.xpath("//*/div[@id='content']//text()")
    print(content)

img

采用chatgpt:
代码中有几个问题需要解决:

1、标头不正确:标头字典包含无效键。 标头应指定为键值对,但在当前代码中,仅提供值。 要解决此问题,请更新标头字典,如下所示:

headers = {
    'authority': 'pagead2.googlesyndication.com',
    'method': 'GET',
    'path': '/getconfig/sodar?sv=200&tid=gda&tv=r20230718&st=env',
    'scheme': 'https',
    'accept': '*/*',
    'accept-encoding': 'gzip, deflate, br',
    'accept-language': 'zh-CN,zh;q=0.9',
    'origin': 'https://www.qb5200.la',
    'referer': 'https://www.qb5200.la/',
    'sec-ch-ua': '";Not A Brand";v="99", "Chromium";v="94"',
    'sec-ch-ua-mobile': '?0',
    'sec-ch-ua-platform': '"Windows"',
    'sec-fetch-dest': 'empt',
    'sec-fetch-mode': 'cors',
    'sec-fetch-site': 'cross-site',
    'user-agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/94.0.4606.71 Safari/537.36',
}

不正确的正则表达式模式:用于查找 TOC(目录)块的正则表达式模式缺少右双引号。 修改模式如下:

toc_block = re.findall('<dl class="zjlist">(.*?)</dl>', html, re.S)[0]

函数返回缩进不正确:return toc_url_list 语句应放在 get_toc 函数中的 for 循环之外。 否则,该函数将在第一次迭代后返回,导致仅提取一个 URL。 像这样修复它:

def get_toc(html):
    toc_url_list = []
    toc_block = re.findall('<dl class="zjlist">(.*?)</dl>', html, re.S)[0]
    toc_url = re.findall('href="(.*?)"', toc_block, re.S)
    for url in toc_url:
        toc_url_list.append(start_url + url)
    return toc_url_list

get_article 函数中的变量名称不正确:您似乎想使用chapter_name 变量,而不是chapter_namez。 修复如下:

def get_article(html):
    chapter_name = re.search('<div class="border">(.*?)</div>', html, re.S).group(1)
    chapter_name = chapter_name.select('h1:nth-of-type(1)')  # Assuming you want to keep this line, although it's unclear what the 'select' method does.
    text_block = re.search('<div id="content">(.*?)</div>', html, re.S).group(1)
    text_block = text_block.replace('<br>', '')
    return chapter_name, text_block

保存函数中的文件名不正确:chapter_namez 变量是一个列表(因为您使用了 select 方法),因此您不能直接使用它作为文件名。 相反,您应该从列表中提取字符串或考虑使用不同的标识符作为章节名称。 假设您想要列表中的第一个元素,请像这样更新函数:

def save(chapter_namez, text_block):
    os.makedirs('星门', exist_ok=True)
    chapter_name = chapter_namez[0] if chapter_namez else 'Unknown_Chapter_Name'
    with open(os.path.join('星门', chapter_name + '.txt'), 'w', encoding='gbk') as f:
        f.write(text_block)

通过这些更正,代码应该可以更好地工作。 请记住调用函数 get_toc、get_article 和 save 来实际执行网页抓取并保存数据。



引用chatgpt


import requests
from bs4 import BeautifulSoup

def get_novel_content(url):
    # 发送 HTTP 请求获取页面内容
    response = requests.get(url)
    response.encoding = 'utf-8'
    html = response.text

    # 使用 BeautifulSoup 解析页面内容
    soup = BeautifulSoup(html, 'html.parser')

    # 获取小说标题
    title = soup.find('h1').text.strip()

    # 获取小说章节列表
    chapters = soup.find('div', class_='book-list').find_all('a')

    # 遍历章节列表,爬取每个章节的内容
    for chapter in chapters:
        chapter_title = chapter.text.strip()
        chapter_url = chapter['href']
        chapter_content = get_chapter_content(chapter_url)

        # 打印章节标题和内容
        print(f'章节标题:{chapter_title}')
        print('内容:')
        print(chapter_content)
        print('===============================')

def get_chapter_content(url):
    # 发送 HTTP 请求获取章节内容
    response = requests.get(url)
    response.encoding = 'utf-8'
    html = response.text

    # 使用 BeautifulSoup 解析页面内容
    soup = BeautifulSoup(html, 'html.parser')

    # 获取章节内容
    content = soup.find('div', class_='content').text.strip()

    return content

# 测试
novel_url = 'http://www.example.com/novel'
get_novel_content(novel_url)

  1. URL设置问题:在请求的headers中,':authority'、':method'、':path'、':scheme'等字段应该作为键值对的一部分,不需要使用冒号作为键名。

  2. 编码问题:根据你的代码,在解码HTML时使用了'gbk'编码,但是根据网页的编码方式可能会有所不同。你可以尝试使用'utf-8'编码或者通过查看网页源代码来确定正确的编码方式。

  3. 函数缩进问题:在你的代码中,get_tocget_article两个函数的返回值列表在循环内部被添加数据,导致最后只返回了一个URL。你需要修改代码使得返回的URL列表包含所有的URL。

你确定你发的是完整的代码吗?

有几个问题可能导致你无法成功爬取小说内容:

网站反爬虫机制:一些网站会通过一些手段来防止被爬取,比如验证码、动态加载内容等。你可以尝试使用浏览器开发者工具分析网站的请求和响应,检查是否有需要处理的反爬虫措施。

网页解析错误:在你的代码中,解析小说章节链接的正则表达式可能存在问题,导致无法获取到正确的链接。请确保正则表达式的模式正确,并且与网页内容匹配。

文件保存路径问题:在保存小说章节内容时,你使用了一个变量 chapter_namez,但在后面保存文件时却错误地使用了 chapter_namez 作为文件名。请确保文件名的正确性,可以使用调试功能来检查变量的值。

另外,请注意爬取小说的合法性。确保你对目标网站的爬取行为符合网站的使用条款,并尊重版权和法律的规定。

  • 你可以看下这个问题的回答https://ask.csdn.net/questions/7618339
  • 你也可以参考下这篇文章:Python爬虫 | 爬取全书网小说斗罗大陆
  • 你还可以看下python参考手册中的 python- 自定义扩展类型:教程- 基础
  • 您还可以看一下 阿尔法老师的Python爬虫开发入门课程中的 第七讲:爬虫程序改造小节, 巩固相关知识点
  • 以下回答由chatgpt基于相关博客总结生成:

    问题分析: 根据提供的代码,无法确定具体无法成功爬取小说内容的原因。可能的原因包括: 1. 请求返回的网页内容不是所期望的小说内容,导致无法找到目标div元素。 2. 网站有反爬机制,导致请求被拦截或者无法正确解析网页内容。 3. 网站的网页结构发生了变化,导致无法正确定位目标div元素。 4. 网站需要登录或者进行其他身份验证。

    解决方案: 1. 确认请求返回的网页内容是否是所期望的小说内容。可以使用print(response.text)输出网页内容,检查是否包含小说内容。 2. 如果遇到反爬机制,可以尝试使用请求头的方式绕过反爬机制。设置headers参数传递给requests.get()方法,例如:

    headers = {
        'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/58.0.3029.110 Safari/537.3'}
    response = requests.get(url, headers=headers)
    
    1. 如果网页结构发生了变化,可以根据新的网页结构修改代码中的选择器,确保能够正确定位到目标div元素。可以使用浏览器的开发者工具查看网页源码,找到div元素的class或者其他属性,修改代码中的选择器。
    2. 如果网站需要登录或者进行其他身份验证,可以先尝试手动登录该网站,在浏览器中查看登录后的请求的请求头和响应头信息,然后在代码中模拟登录过程,以获取合法的网页内容。

    补充说明:以上提供的是一般的问题分析和解决方案,具体情况需根据实际网站和代码情况进行分析和调试。如果对爬虫技术不熟悉,可以参考更多的爬虫教程和文档学习。

定义了函数但是没有调用运行啊