吾爱破解 - 52pojie.cn

 找回密码
 注册[Register]

QQ登录

只需一步,快速开始

查看: 4429|回复: 35
收起左侧

[Python 转载] 您的【python爬虫入门实战练习-爬取当当网前500书单】已送达,开门取一下

  [复制链接]
完成大我 发表于 2020-8-8 09:07
本帖最后由 完成大我 于 2020-8-8 09:14 编辑

我是一名新手,刚开始学习python爬虫,自己的分析过程分享给一起学习的新手小伙伴,大神们就别看了
1.环境准备
- 爬取网页信息首先要进行网页请求,本次实战使用Requests
- 获取html信息后,想要获取指定的信息,就需要用到正则匹配网页,pyhton的re模块可实现正则匹配功能
- BeautifulSoup是高效的网页解析库,可以从 HTML 或 XML 文件中提取数据,可以省去编写复杂的正则表达式,快速找到目标;我们用的比较多的是 lxml 解析器
工欲善其事,必先利其器>>先把库装好:

[Python] 纯文本查看 复制代码
[/backcolor]
[backcolor=rgb(249, 249, 249)]pip install re[/backcolor]
[backcolor=rgb(249, 249, 249)]pip install requests[/backcolor]
[backcolor=rgb(249, 249, 249)]pip install beautifulsoup4[/backcolor]
[backcolor=rgb(249, 249, 249)]pip install lxml[/backcolor]
[backcolor=rgb(249, 249, 249)]

2.爬取方案分析
2.1.本例目标网页
经典案例:http://bang.dangdang.com/books/f ... 00-recent30-0-0-1-1
微信截图_20200807215422.png
2.2.目标爬取信息
  • 书籍排名
  • 书籍名称
  • 书籍出版信息
  • ...其他信息自选,原理类似,可做练习使用

2.3.html分析
返回html中搜索第一本书书名,发现第一本书的信息全部包含在\<li>标签内,具体信息又包含在\<li>中的每个\<div>内,包括list_num(书籍排名),pic(封面),name(书名),star(星级),publisher_info(出版信息),biaosheng(五星评分次数),price(价格)
clipboard.png
2.4.多页面切换
我们的目标是爬取前五百本书籍信息,但是http://bang.dangdang.com/books/f ... 00-recent30-0-0-1-1这个页面只有20本书怎么办?点击下一页发现地址为:http://bang.dangdang.com/books/f ... 00-recent30-0-0-1-2,第三页地址为....-3,以此类推,所以网页请求可以用以下形式实现。
[HTML] 纯文本查看 复制代码
"http://bang.dangdang.com/books/fivestars/01.00.00.00.00.00-recent30-0-0-1-"+数字

2.5.方案步骤
  • 获取页面html
  • 解析获取当前html内所有的\<li>标签内内容
  • 每个\<li>标签内匹配书籍排名、名称、出版信息并输出;循环直到解析完所有\<li>
  • 循环获取每一页html,重复2,3,直到最后一页(25页)

2.6.正则编写
子曰:不懂正则怎么躺着爬虫,如果你不懂正则,[赶快来学](https://www.runoob.com/regexp/regexp-tutorial.html)

书籍排名:
前三本书类名为"list_num red",但从第四本书开始类名变为"list_num",他们有共同点"list_num"

[HTML] 纯文本查看 复制代码
<div class="list_num red">1.</div>
 <div class="list_num ">4.</div> 


我们要找的目标是其中的数字,因此匹配正则可以写为

[Python] 纯文本查看 复制代码
list_num.*?(\d*?)\..*?>


书籍名称:
书籍名称\<div>类名均为"name"
[HTML] 纯文本查看 复制代码
 <div class="name"><a href="http://product.dangdang.com/25197810.html" target="_blank" title="尤尔小屋的猫">尤尔小屋的猫</a></div>


我们要找的目标是title的值,因此匹配正则可以写为
[Python] 纯文本查看 复制代码
<div class="name">.*?title="(.*?)">.*?>

书籍出版信息:
同样出版信息\<div>类名均为"publisher_info"

[Python] 纯文本查看 复制代码
<div class="publisher_info"><a href="http://search.dangdang.com/?key=朱光潜" title="朱光潜,酷威文化 出品" target="_blank">朱光潜</a>


我们要找的目标是title的值,因此匹配正则可以写为

[Python] 纯文本查看 复制代码
<div class="publisher_info">.*?title="(.*?)">.*?>


3.代码
是不是知到怎么弄了,整活
[Python] 纯文本查看 复制代码
# -*- coding: utf-8 -*-
# [url=home.php?mod=space&uid=238618]@Time[/url]    : 2020/8/8 8:07
# [url=home.php?mod=space&uid=686208]@AuThor[/url]  : guojian1
# @FileName: book_crawler.py
# @Software: PyCharm
import requests
import re
from bs4 import BeautifulSoup
import json
#get请求方法,返回结果文本字符串
def request_dandan(url):
   try:
       response = requests.get(url)
       if response.status_code == 200:
           return response.text
   except requests.RequestException:
       return None
#写入txt文件方法
def write_item_to_file(item):
   print('开始写入数据 ====> ' + str(item))
   with open('book.txt', 'a', encoding='UTF-8') as f:
       f.write(json.dumps(item, ensure_ascii=False) + '\n')
       f.close()
#主方法
def main(page):
    #获取当当网好评榜页面html
    url = 'http://bang.dangdang.com/books/fivestars/01.00.00.00.00.00-recent30-0-0-1-' + str(page)
    html = request_dandan(url)
    #解析返回的html
    soup = BeautifulSoup(html, 'lxml')
    #找到所有<li>标签项(本次实战爬取书名、出版信息;都可在li标签内找到)
    all_lis = soup.find_all('li')
    #循环爬取所有<li>中的目标对象
    for li in all_lis:
        init_dict = {}
        #正则匹配书名,出版信息
        searchObj1 = re.search(r'list_num.*?(\d*?)\..*?>', str(li), re.M | re.I)
        searchObj2 = re.search(r'<div class="name">.*?title="(.*?)">.*?>', str(li), re.M | re.I)
        searchObj3 = re.search(r'<div class="publisher_info">.*?title="(.*?)">.*?>', str(li), re.M | re.I)
        #书名与出版信息非空时,将匹配结果赋值给字典
        if searchObj1 and searchObj2 and searchObj3:
            init_dict['list_num']=searchObj1.group(1)
            init_dict["name"] = searchObj2.group(1)
            init_dict["publisher_info"] = searchObj3.group(1)
        if init_dict:
            write_item_to_file(init_dict)

if __name__ == "__main__":
    #获取1-26页信息
   for i in range(1,26):
       main(i)





免费评分

参与人数 4吾爱币 +1 热心值 +4 收起 理由
BrFEzL + 1 用心讨论,共获提升!
6到家 + 1 我很赞同!
yankaiyang + 1 + 1 我很赞同!
荷塘夜色 + 1 用心讨论,共获提升!

查看全部评分

发帖前要善用论坛搜索功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。

jayfox 发表于 2020-8-9 14:42
Ldfd 发表于 2020-8-8 10:10
/html/body/div[3]/div[3]/div[2]/ul/li
  • /div[3]/a/text()
    一句xpath完事

  • 确实  感觉正则不好写 还容易出错  xpath 简单快捷
    Ldfd 发表于 2020-8-9 15:18
    jayfox 发表于 2020-8-9 14:42
    确实  感觉正则不好写 还容易出错  xpath 简单快捷

    浏览器的 copy Xpath太无赖了哈哈,加个通配符就能用
    lypxynok 发表于 2020-8-8 09:16
    大屈帝 发表于 2020-8-8 09:18
    厉害,学到了
    老猫Van 发表于 2020-8-8 09:23
    学习了,准备自己试试,谢谢楼主。
    popoyu521 发表于 2020-8-8 09:30
    多谢楼主提供的方法,学习了
    jokony 发表于 2020-8-8 09:35
    支持鼓励一下。。
    huahaiYa 发表于 2020-8-8 09:37
    首先多谢楼主的分享,有个问题想问一下,当当有反扒机制吗?
    阿白L 发表于 2020-8-8 09:41
    学到了,多谢楼主
    CCQc 发表于 2020-8-8 09:41
    楼主太专业了,老百姓看不懂
    九星辰楪 发表于 2020-8-8 09:46
    学习了 感谢分享
    您需要登录后才可以回帖 登录 | 注册[Register]

    本版积分规则

    返回列表

    RSS订阅|小黑屋|处罚记录|联系我们|吾爱破解 - LCG - LSG ( 京ICP备16042023号 | 京公网安备 11010502030087号 )

    GMT+8, 2024-11-26 01:45

    Powered by Discuz!

    Copyright © 2001-2020, Tencent Cloud.

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