鱼C论坛

 找回密码
 立即注册
查看: 2057|回复: 2

[技术交流] 爬虫实战 - 豆瓣图书Top 250 (xpath方法演练)

[复制链接]
发表于 2018-2-3 12:42:17 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
本帖最后由 payton24 于 2018-2-3 18:01 编辑

豆瓣的资料还是挺多的,继续爬。上一篇用copy xpath的路径比较靠谱,这次继续用。
这次爬豆瓣图书Top250。

爬取网址:https://book.douban.com/top250
爬取信息:书名、书名链接,评价、评价人数、一句话点评

先爬书名,一下子掉进了坑,原来是chrome、Firefox等浏览器为了对html文本进行规范化,在table标签下添加了tbody。
使用【查看网页源代码】和【审查】来进行比较,就能清楚看到上述结果。
于是,果断去掉table后面的/tbody。
  1. 原xpath路径:    //*[@id="content"]/div/div[1]/div/table[1]/tbody/tr/td[2]/div[1]/a
  2. 替换xpath路径://*[@id="content"]/div/div[1]/div/table[1]/tr/td[2]/div[1]/a
复制代码


①第一本图书信息的代码为:
  1. import requests
  2. from lxml import etree

  3. url = 'https://book.douban.com/top250'
  4. r = requests.get(url)
  5. #print(r.status_code)
  6. selector = etree.HTML(r.text)

  7. # book_name = selector.xpath('//*[@id="content"]/div/div[1]/div/table[1]/tbody/tr/td[2]/div[1]/a/text()')
  8. book_name = selector.xpath('//*[@id="content"]/div/div[1]/div/table[1]/tr/td[2]/div[1]/a/@title')
  9. rating = selector.xpath('//*[@id="content"]/div/div[1]/div/table[1]/tr/td[2]/div[2]/span[2]/text()')
  10. rating_num = selector.xpath('//*[@id="content"]/div/div[1]/div/table[1]/tr/td[2]/div[2]/span[3]/text()')
  11. comment = selector.xpath('//*[@id="content"]/div/div[1]/div/table[1]/tr/td[2]/p[2]/span/text()')
  12. book_link = selector.xpath('//*[@id="content"]/div/div[1]/div/table[1]/tr/td[2]/div[1]/a/@href')

  13. print(book_name , rating, rating_num, comment, book_link)
复制代码


要爬取多本图书的信息,只需列出多本图书的xpath信息进行观察,结果发现table序号不断增加,以书名为例:
//*[@id="content"]/div/div[1]/div/table[1]/tr/td[2]/div[1]/a
//*[@id="content"]/div/div[1]/div/table[2]/tr/td[2]/div[1]/a
//*[@id="content"]/div/div[1]/div/table[3]/tr/td[2]/div[1]/a
//*[@id="content"]/div/div[1]/div/table[4]/tr/td[2]/div[1]/a

②所以获取多本图书书名的xpath路径为:
//*[@id="content"]/div/div[1]/div/table/tr/td[2]/div[1]/a

整理后的代码为:
  1. import requests
  2. from lxml import etree

  3. url = 'https://book.douban.com/top250'
  4. r = requests.get(url)
  5. #print(r.status_code)
  6. selector = etree.HTML(r.text)

  7. book_names = selector.xpath('//*[@id="content"]/div/div[1]/div/table/tr/td[2]/div[1]/a/@title')
  8. ratings = selector.xpath('//*[@id="content"]/div/div[1]/div/table/tr/td[2]/div[2]/span[2]/text()')
  9. rating_nums = selector.xpath('//*[@id="content"]/div/div[1]/div/table/tr/td[2]/div[2]/span[3]/text()')
  10. comments = selector.xpath('//*[@id="content"]/div/div[1]/div/table/tr/td[2]/p[2]/span/text()')
  11. book_links = selector.xpath('//*[@id="content"]/div/div[1]/div/table/tr/td[2]/div[1]/a/@href')

  12. print(book_names , ratings, rating_nums, comments, book_links)
复制代码


③另外,上述获取书名、链接的xpath路径有重叠,所以实际操作往往先提取前面重复部分,并将列表中的内容提取出来处理。
  1. books = selector.xpath('//*[@id="content"]/div/div[1]/div/table/tr/td[2]')
  2. for book in books:
  3.     book_name = book.xpath('./div[1]/a/@title')[0]   
  4.     rating = book.xpath('./div[2]/span[2]/text()')[0]
  5.     rating_num = book.xpath('./div[2]/span[3]/text()')[0].strip('()\n ')  #去除包含"(",")","\n"," "的首尾字符
  6.     comment = book.xpath('./p[2]/span/text()')[0]
  7.     book_link = book.xpath('./div[1]/a/@href')[0]
  8.     print(book_name ,rating, rating_num,comment, book_link)
复制代码


④多页面信息爬取,观察页面规律:
  1. https://book.douban.com/top250?start=0
  2. https://book.douban.com/top250?start=25
  3. https://book.douban.com/top250?start=50
  4. https://book.douban.com/top250?start=75
复制代码

很明显,每页最后的数字从0开始,依次递增25,所以可构造一个url列表:
  1. urls = ['https://book.douban.com/top250?start={}'.format(i * 25) for i in range(10)]
复制代码


⑤附上全部代码,由于某些书不存在评论,故而使用了try语句:
  1. import requests
  2. from lxml import etree
  3. import time

  4. urls = ['https://book.douban.com/top250?start={}'.format(i * 25) for i in range(10)]
  5. for url in urls:
  6.     r = requests.get(url)
  7.     selector = etree.HTML(r.text)
  8.    
  9.     books = selector.xpath('//*[@id="content"]/div/div[1]/div/table/tr/td[2]')
  10.     for book in books:
  11.         book_name = book.xpath('./div[1]/a/@title')[0]   
  12.         rating = book.xpath('./div[2]/span[2]/text()')[0]
  13.         rating_num = book.xpath('./div[2]/span[3]/text()')[0].strip('()\n ')  #去除包含"(",")","\n"," "的首尾字符
  14.         try:
  15.             comment = book.xpath('./p[2]/span/text()')[0]
  16.         except:
  17.             comment = ""
  18.         book_link = book.xpath('./div[1]/a/@href')[0]
  19.         print(book_name ,rating, rating_num,comment, book_link)
  20.         
  21.     time.sleep(3)
复制代码












小甲鱼最新课程 -> https://ilovefishc.com
回复

使用道具 举报

发表于 2018-2-3 13:18:47 | 显示全部楼层
感谢分享
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2018-2-3 18:01:30 | 显示全部楼层
谢谢帮顶,哈哈
小甲鱼最新课程 -> https://ilovefishc.com
回复 支持 反对

使用道具 举报

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

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2025-6-12 20:55

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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