Python爬虫基础之Requests和XPath实例(三)

如何用Python爬取多个页面的数据信息呢?这次通过豆瓣网top250的图书信息来进行学习。首先给出页面(如图1所示)的URL: https://book.douban.com/top250 ,我们要爬去的信息是:书名、链接、评分、一句话评价……
  

在这里插入图片描述
图1

1. 爬取单个信息

首先要是爬取单个页面中单个书本的信息,这个内容上篇文章以及记录过了,代码如下:

import requests
#from lxml import etree
from lxml import html
etree = html.etree
url = 'https://book.douban.com/top250'
data = requests.get(url).text
s=etree.HTML(data)
#通过@title获取他的title标签里面的内容
film=s.xpath('//*[@id="content"]/div/div[1]/div/table[1]/tr/td[2]/div[1]/a/@title')
print('电影名称:',film)

2.爬取多个信息

获取单个页面多个全部书本信息,这样就要看各个页面的xpath的不同:

//*[@id="content"]/div/div[1]/div/table[1]/tbody/tr/td[2]/div[1]/a
//*[@id="content"]/div/div[1]/div/table[2]/tbody/tr/td[2]/div[1]/a
//*[@id="content"]/div/div[1]/div/table[3]/tbody/tr/td[2]/div[1]/a

比较可以发现书名的 xpath 信息仅仅 table 后的序号不一样,并且跟书的序号一致,于是去掉序号(去掉 tbody),我们可以得到通用的 xpath 信息:

//*[@id=“content”]/div/div[1]/div/table/tr/td[2]/div[1]/a
代码
import requests
#from lxml import etree
from lxml import html
etree = html.etree
url = 'https://book.douban.com/top250'
data = requests.get(url).text
s=etree.HTML(data)
#通过@title获取他的title标签里面的内容
film=s.xpath('//*[@id="content"]/div/div[1]/div/table/tr/td[2]/div[1]/a/@title')
for title in film:
    print(title)

结果如图2所示:
  

在这里插入图片描述
图2

同理我们去爬出其他信息,这样就遇到一个问题,怎么去定义循环次数呢?那我们爬出的信息一定会在一个总的标签中,我们只需要向上求最大公约数,就可以找到循环次数。我们将整本书和书名的xpath进行对比,后就可以找到。

//*[@id=“content”]/div/div[1]/div/table[1]   #整本书
//*[@id=“content”]/div/div[1]/div/table[1]/tr/td[2]/div[1]/a   #书名
//*[@id=“content”]/div/div[1]/div/table[1]/tr/td[2]/div[2]/span[2]  

获取单个页面全部信息的代码如下,结果如图3所示:

import requests
#from lxml import etree
from lxml import html
etree = html.etree
url = 'https://book.douban.com/top250'
data = requests.get(url).text
s=etree.HTML(data)
#file用来记录循环次数
file=s.xpath('//*[@id="content"]/div/div[1]/div/table')
#通过@title获取他的title标签里面的内容

for info in file:
    title = info.xpath('./tr/td[2]/div[1]/a/@title')[0]
    href = info.xpath("./tr/td[2]/div[1]/a/@href")[0]
    score = info.xpath('./tr/td[2]/div[2]/span[2]/text()')[0]
    #只取评论的第一条
    commitmentNum=info.xpath('./tr/td[2]/div[2]/span[3]/text()')[0].strip("(").strip().strip(")")
    scribe=info.xpath("./tr/td[2]/p[2]/span/text()")
    print("{}    {}    {}   {}".format(title,href,score,commitmentNum,scribe[0]))


在这里插入图片描述
图3

3.翻页,爬取所有页面信息

先来看一下翻页后url是如何变化的:

https://book.douban.com/top250?start=0   #第一页
https://book.douban.com/top250?start=25   #第二页
https://book.douban.com/top250?start=50   #第三页

url 变化的规律很简单,只是 start=() 的数字不一样而已,而且是以每页25为单位,递增25,这不正是每页的书籍的数量吗?于是,我们只需要写一个循环就可以了,结果如图4所示。

import requests
#from lxml import etree
from lxml import html
for a in range(10):
    url = 'https://book.douban.com/top250?start={}'.format(a*25)
    data = requests.get(url).text
    etree = html.etree
    s=etree.HTML(data)
    #file用来记录循环次数
    file=s.xpath('//*[@id="content"]/div/div[1]/div/table')
    #通过@title获取他的title标签里面的内容

    for info in file:
        title = info.xpath('./tr/td[2]/div[1]/a/@title')[0]
        href = info.xpath("./tr/td[2]/div[1]/a/@href")[0]
        score = info.xpath('./tr/td[2]/div[2]/span[2]/text()')[0]
        #只取评论的第一条
        commitmentNum=info.xpath('./tr/td[2]/div[2]/span[3]/text()')[0].strip("(").strip().strip(")")
        scribe=info.xpath("./tr/td[2]/p[2]/span/text()")
        #防止没有评论出现
        if len(scribe) > 0:
            print("{}     {}     {}     {}     {}\n".format(title,href,score,commitmentNum,scribe[0]))
        else:
            print("{}     {}     {}     {}\n".format(title,href,score,scribe))


在这里插入图片描述
图4

4、问题及总结

①得到第一本书《追风筝的人》的书名xpath如下:

//*[@id="content"]/div/div[1]/div/table[1]/tbody/tr/td[2]/div[1]/a

然后运行,发现竟然为空值,这里需要注意,浏览器复制的 xpath 信息并不是完全可靠的,浏览器经常会自己在里面增加多余的 tbody 标签,我们需要手动把这些标签删掉。
②在这些代码中

title = div.xpath("./tr/td[2]/div[1]/a/@title")[0]    
score=div.xpath("./tr/td[2]/div[2]/span[2]/text()")[0]

为什么这两行后面多了个 [0] 呢?我们之前爬出来的数据是列表,外面带个方框,看着非常难受,列表只有一个值,对其取第一个值就OK。
③有一个点需要注意的是:

num=div.xpath("./tr/td[2]/div[2]/span[3]/text()")[0].strip("(").strip().strip(")")

这行代码用了几个 strip() 方法,()里面表示要删除的内容,strip(“(”) 表示删除左括号, strip() 表示删除空白符,strip(")"表示删除右括号。
④上面翻页的时候URL变化格式是个重点,为了加深印象我们增加一个练习,看下面的URL代码变化:

http://cd.xiaozhu.com/search-duanzufang-p1-0/    #第一页
http://cd.xiaozhu.com/search-duanzufang-p2-0/    #第二页
http://cd.xiaozhu.com/search-duanzufang-p3-0/    #第三页
http://cd.xiaozhu.com/search-duanzufang-p4-0/    #第四页

url 变化的规律很简单,只是 p 后面的数字不一样而已,而且跟页码的序号是一模一样的,这就很好办了……写一个简单的循环来遍历所有的url。

 #我们这里尝试5个页面
for a in range(1,6):    
  url = ‘http://cd.xiaozhu.com/search-duanzufang-p{}-0/.format(a)

⑤如何将数据存到本地文档
写文件时,我们主要用到 with open() 语句:

with open(name,mode,encoding) as file:
  file.write()
  # 注意,with open() 后面的语句有一个缩进
  • name:包含文件名称的字符串,比如:‘xiaozhu.txt’;
  • mode:决定了打开文件的模式,只读/写入/追加等;
  • encoding:表示我们要写入数据的编码,一般为 utf-8 或者 gbk ;
  • file:表示我们在代码中对文件的命名。如图5所示
import requests#from lxml import etree
from lxml import html
with open('C:/Users/Administrator/Desktop/1.csv','w',encoding='utf-8') as f:
    for a in range(10):
        url = 'https://book.douban.com/top250?start={}'.format(a*25)
        data = requests.get(url).text
        etree = html.etree
        s=etree.HTML(data)
        file=s.xpath('//*[@id="content"]/div/div[1]/div/table')
        for info in file:
            title = info.xpath('./tr/td[2]/div[1]/a/@title')[0]
            href = info.xpath("./tr/td[2]/div[1]/a/@href")[0]
            score = info.xpath('./tr/td[2]/div[2]/span[2]/text()')[0]
            commitmentNum=info.xpath('./tr/td[2]/div[2]/span[3]/text()')[0].strip("(").strip().strip(")")
            scribe=info.xpath("./tr/td[2]/p[2]/span/text()")
            if len(scribe) > 0:
                f.write("{},{},{},{},{}\n".format(title,href,score,commitmentNum,scribe[0]))
            else:
                f.write("{},{},{},{}\n".format(title, href, score, commitmentNum))

⑥Excel 打开 CSV 出现乱码怎么办?
在记事本中打开文件
另存为 – 选择编码为“ANSI”

评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值