本帖最后由 完成大我 于 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
2.2.目标爬取信息
- 书籍排名
- 书籍名称
- 书籍出版信息
- ...其他信息自选,原理类似,可做练习使用
2.3.html分析
返回html中搜索第一本书书名,发现第一本书的信息全部包含在\<li>标签内,具体信息又包含在\<li>中的每个\<div>内,包括list_num(书籍排名),pic(封面),name(书名),star(星级),publisher_info(出版信息),biaosheng(五星评分次数),price(价格)
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.正则编写
书籍排名:
前三本书类名为"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)
|