找回密码
 立即注册

扫一扫,访问微社区

QQ登录

只需一步,快速开始

查看: 4068|回复: 5

[求助] xpath爬豆瓣网信息 出错

2

主题

5

帖子

5

积分

贫民

积分
5
QQ
如我 发表于 2018-11-16 15:31:25 | 显示全部楼层 |阅读模式
import requests
from lxml import etree
import csv

fp = open ('C://Users/74765/Desktop/doubanbook_top250.csv','wt',newline='',encoding = 'utf-8')
writer = csv.writer(fp)
writer.writerow(('name','url','author','publisher','date','price','rate','commment'))
urls = ['https://book.douban.com/top250?start={}'.format(str(i)) for i in range (0,250,25)]

headers = {
    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.102 Safari/537.36'
}

for url in urls:
    html = requests.get(url,headers = headers)
    selector = etree.HTML(html.text)
    infos = selector.xpath('//*[@id="content"]')
    for info in infos:
        name = info.xpath('td/div/a/@title')[0]
        url = info.xpath('td/div/a/@href')[0]
        book_infos = info.xpath('td/div/p/text()')[0]
        author = book_infos.split('/')[0]
        publisher = book_infos.split('/')[-3]
        date = book_infos.split('/')[-2]
        price = book_infos.split('/')[-1]
        rate = info.xpath('td/div/span[2]/text()')[0]
        comments = info.xpath('td/p/span/text()')
        comment = comments[0] if len(comments) != 0 else "空"
        writer.writerow((name,url,author,publisher,date,price,rate,comments))

fp.close()


最后错误提示:
---------------------------------------------------------------------------IndexError                                Traceback (most recent call last)<ipython-input-1-e56919707679> in <module>()     17     infos = selector.xpath('//*[@id="content"]')     18     for info in infos:---> 19         name = info.xpath('td/div/a/@title')[0]     20         url = info.xpath('td/div/a/@href')[0]     21         book_infos = info.xpath('td/div/p/text()')[0]IndexError: list index out of range
请大家帮我看一下
回复

使用道具 举报

3

主题

278

帖子

278

积分

侠客

积分
278

热心会员

uitb 发表于 2018-11-17 11:53:21 | 显示全部楼层
这种一般加个try...except,有些页面可能找不到你需要的节点,人家就返回一个空列表,你还去对这个列表进行index操作,肯定会报错啊
回复 支持 反对

使用道具 举报

2

主题

5

帖子

5

积分

贫民

积分
5
QQ
如我  楼主| 发表于 2018-11-18 11:07:42 | 显示全部楼层
uitb 发表于 2018-11-17 11:53
这种一般加个try...except,有些页面可能找不到你需要的节点,人家就返回一个空列表,你还去对这个列表进行i ...

感谢帮助
但是我并没有对list进行index操作,我感觉我应该是对xpath的理解不多,导致的错误,try    except方法我试着加进来。
回复 支持 反对

使用道具 举报

3

主题

278

帖子

278

积分

侠客

积分
278

热心会员

uitb 发表于 2018-11-18 18:11:12 | 显示全部楼层
本帖最后由 uitb 于 2018-11-18 18:12 编辑
如我 发表于 2018-11-18 11:07
感谢帮助
但是我并没有对list进行index操作,我感觉我应该是对xpath的理解不多,导致的错误,try    exce ...

info.xpath('td/div/a/@title')[0] ,你报错在这句,不就是在对列表进行index(索引)操作,报错信息也是列表索引超出范围,info.xpath('td/div/a/@title')这句返回的是个列表,如果没找到,就是个空列表,[0]就是在对列表进行索引
回复 支持 反对

使用道具 举报

2

主题

5

帖子

5

积分

贫民

积分
5
QQ
如我  楼主| 发表于 2018-11-18 22:41:44 | 显示全部楼层
uitb 发表于 2018-11-18 18:11
info.xpath('td/div/a/@title')[0] ,你报错在这句,不就是在对列表进行index(索引)操作,报错信息也是 ...

感谢,我已经成功的把问题解决 了
回复 支持 反对

使用道具 举报

2

主题

5

帖子

5

积分

贫民

积分
5
QQ
如我  楼主| 发表于 2018-11-18 23:16:43 | 显示全部楼层
问题已经解决了,我把代码贴出来

# -*- coding: utf-8 -*-

import requests as req
from lxml import etree
import csv
import time

header = {'User-Agent':'Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/55.0.2883.87 Safari/537.36'}
f = open('douban_book_250.csv', 'w+', encoding = 'utf-8')
doubanbook = csv.writer(f)
doubanbook.writerow(('book', 'writer', 'publisher', 'date', 'price', 'rate', 'reader', 'comment', 'cover'))

for i in range(0, 10):
    print('--------------------现在开始爬取第' + str(i+1) + '页--------------------')
    url = 'https://book.douban.com/top250?start=' + str(25*i)
    resp**e = req.get(url, headers = header)
    xml = etree.HTML(resp**e.content)

    for j in range(1,26):

        books_xpath = '//*[@id="content"]/div/div[1]/div/table[' + str(j) + ']/tr/td[2]/div[1]/a/text()'
        books = xml.xpath(books_xpath)[0].strip()

        try:
            writers_xpath = '//*[@id="content"]/div/div[1]/div/table[' + str(j) + ']/tr/td[2]/p[1]/text()'
            infos = xml.xpath(writers_xpath)[0].strip()#strip函数进行去除‘/’
            writers = infos.split('/')[-4]#split()函数通过指定分隔符进行切片
            publisher = infos.split('/')[-3]
            date = infos.split('/')[-2]
            price = infos.split('/')[-1]
        except(TypeError, IndexError):
            writers_xpath = '//*[@id="content"]/div/div[1]/div/table[' + str(j) + ']/tr/td[2]/p[1]/text()'
            infos = xml.xpath(writers_xpath)[0].strip()#strip函数进行去除‘/’
            publisher = infos.split('/')[-3]
            date = infos.split('/')[-2]
            price = infos.split('/')[-1]      
        
        ratings_xpath = '//*[@id="content"]/div/div[1]/div/table[' + str(j) + ']/tr/td[2]/div[2]/span[2]/text()'
        ratings = xml.xpath(ratings_xpath)[0].strip()

        readers_xpath = '//*[@id="content"]/div/div[1]/div/table[' + str(j) + ']/tr/td[2]/div[2]/span[3]/text()'
        readers = xml.xpath(readers_xpath)[0].strip('()').strip()

        comments_xpath = '//*[@id="content"]/div/div[1]/div/table[' + str(j) + ']/tr/td[2]/p[2]/span/text()'
        comment = xml.xpath(comments_xpath)
        if len(comment) != 0:
            comments = xml.xpath(comments_xpath)[0].strip()
        else:
            comments = '空白'

        imgs_xpath = '//*[@id="content"]/div/div[1]/div/table[' + str(j) + ']/tr/td[1]/a/img/@src'
        imgs = xml.xpath(imgs_xpath)[0].strip()

        doubanbook.writerow((books, writers, publisher, date, price, ratings, readers, comments, imgs))

        print(books)
        print(writers)
        print(publisher)
        print(date)
        print(price)
        print(ratings)
        print(readers)
        print(comments)
        print(imgs + '\n')

    time.sleep(0.5)   
    print(3*'\n')

f.close()
print('OK')
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

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