前言:这是学习Python的第三天,草草查阅了Python基础语法之后想写个demo练练手。找到一篇,效仿着写了一遍,对于初学Python爬虫的人来说是个很好的学习案例。以下是代码解读和关键点标注。
使用语言:Python3.7
开发工具:PyCharm
引用地址:
[https://my.oschina.net/u/3887904/blog/2965738]:
包的引用
# re库,提供正则表达式支持
import re
import json
# requests库,提供HTTP支持
import requests
from requests import RequestException
注意: python毕竟是个脚本语言,从上到下执行,因此写函数的时候需要注意先后顺序,最先调用的写在文件最上方,main函数一般在最下方,否则会报'XXX' is not defined喔!
执行步骤
1、通过url获取网页内容
# 通过url地址拿到网页内容
def get_page(url):
try:
result = requests.get(url)
if result.status_code == 200:
return result.text
return None
except RequestException:
return None
这里写法比较固定,你可能需要去了解的是HTTP各种状态码:
[https://baike.baidu.com/item/HTTP%E7%8A%B6%E6%80%81%E7%A0%81/5053660?fr=aladdin]:
2、正则解析
# 正则表达式解析网页数据,获取想要的信息
def compile_html(html):
pattern = re.compile('<li>.*?list_num.*?>(.*?).</div>.*?<img.*?src="(.*?)".*?class="name".*?title="(.*?)".*?class="tuijian">(.*?)</span>.*?</li>', re.S)
items = re.findall(pattern, html)
for item in items:
yield {
'index': item[0],
'image': item[1],
'title': item[2],
'introducePercent': item[3]
}
这里你需要注意两部分:
- 正则的写法
话说我在今天之前,对正则的理解真的→0,好在这里的正则不难。“.*?”三个符号构成一个模糊替换单位,如果(.*?)使用括号括起来,表示括号内的内容就是你要获取的内容。你只需要写出.*?x(.*?)y.*?就可以过滤出元素x与y之间的数据了,easy HA~?
- compile与findall
首先,re.compile(pattern, flags)的解释:
pattern 指定编译时的表达式字符串;
flags 编译标志位,用来声明正则表达式的匹配方式。支持 re.L|re.M 同时匹配
所以,这里pattern 不需要解释,这里的flags的声明可查文档,例:re.S 代表匹配包括换行在内的所有字符。
所以re.findall(pattern, html)还需要解释?返回匹配成功的对象啊!
到此,这篇文章的核心代码其实也就结束了。。。Yeah~ That’s it.
3、写入文件
# 把数据保存在本地
def save_to_txt(item):
with open("books.txt", "a+", encoding="utf-8") as file:
file.write(json.dumps(item, ensure_ascii=False) + "\n")
file.close()
这里需要注意俩部分:
-
open的时候声明一下编码方式
-
json.dumps(item, ensure_ascii=False)
(1) json.dumps() 将字典转化为字符串;
(2) ensure_ascii=False:json.dumps 序列化时对中文默认使用ascii编码,想输出真正的中文需要指定ensure_ascii=False
4、整体实现
# 主函数模块
def main(pageIndex):
# 根据不同页数获取对应页面数据,当当网每条数据在20条
url = "http://bang.dangdang.com/books/bestsellers/01.00.00.00.00.00-24hours-0-0-1-" + str(pageIndex)
# 获取url中的网页内容
html = get_page(url)
# 正则表达式获取每条信息并打印,打印后存入本地文本文件
for item in compile_html(html):
print(item)
save_to_txt(item)
if __name__ == '__main__':
for i in range(1, 6):
main(i)
嗯,整体代码比较简单,初学python很适合。Over~