爬虫初级二(爬中国古诗文网)
第一步先分析要爬取网站的网址
为什么要先分析网址呢?通过网址我们可以知道此网页页面是异步请求(post)还是同步请求(get)
get请求:最常见的HTTP请求方式,普通上网浏览页面使用的就是get请求方式。get请求方式的参数直接跟在url后,一般以?开始。
post请求:post请求的参数没有直接跟在url后边,这个参数需要自己找,找到后用&连接到url后边。这里用到的是get请求就不说怎要找post请求的参数了
要爬取的url
url=“https://www.gswen.cn/ancient/0/0/0/68/0/0/”
第二步获取HTML文件
话不多说,直接上代码:
#导入urllib库
from urllib import request
#url
url="https://www.gswen.cn/ancient/0/0/0/68/0/0/"
#请求头
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.193 Safari/537.36"
}
res = request.Request(url=url,headers=headers)
#开启请求
response = request.urlopen(res)
#将请求到的数据存入文件中
with open("1.html","w",encoding="utf-8")as f:
f.write(response.read().decode("utf-8"))
第三步获取处理数据
首先选择正则匹配
匹配之前要先查找需要的内容在哪个位置,前后有什么内容有什么特别之处,争取用最少的代码匹配到所有需要的内容,先匹配唐诗300首的题目吧:
经过辛苦的工作后发现在h3标签下存在a标签的就只有古诗的标题了,那就只要把a标签内的内容取出就行了,如下代码:
#将请求到的数据存入变量html中
html = response.read().decode("utf-8")
#匹配内容
reg = r'<h3><a.*?>(.*?)</a>'
#获取匹配结果
result = re.findall(reg,html)
print(result)
正则匹配太费经了再来试试xpath
首先要使用xpath工具找到要抓取内容的位置
再在代码中是实现
#初始化一个etree对象
html_ = etree.HTML(html)
# 用xpath匹配
result = html_.xpath('//div[@class="conview conview_main show"]/div/text()')
#遍历输出结果
for row in result:
print(row)
这存在一个问题,诗的句数不确定,得到的古诗中诗与诗之间没用任何分隔的标志这后期处理很麻烦,这个方法也不可取
再试试BeautifulSoup匹配
#先创建一个BeautifulSoup对象
soup = BeautifulSoup(html,"lxml")
#使用css选择匹配
result = soup.select(".conview_main")
#遍历打印结果
for row in result:
print(row.get_text())
这个可以满足要求
第四步将数据存入MySQL数据库
直接上整体代码
#导入urllib库
from urllib import request
#导入bs4库
from bs4 import BeautifulSoup
#导入数据库连接类
from pa.connect import ConnectMysql
#获取html
def get_html(num):
#url
url="https://www.gswen.cn/ancient/0/0/0/68/0/%d/"%num
#请求头
headers = {
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/86.0.4240.193 Safari/537.36"
}
res = request.Request(url=url,headers=headers)
#开启请求
response = request.urlopen(res)
#将请求到的数据存入变量html中
html = response.read().decode("utf-8")
return data_processing(html)
#数据处理
def data_processing(html):
data_lists = [] #用于存储古诗数据
#先创建一个BeautifulSoup对象
soup = BeautifulSoup(html,"lxml")
#使用css选择匹配题目
subject = soup.select(".t h3")
#使用css选择匹配作者和朝代
dynasty_author = soup.select(".zz span")
#使用css选择匹配诗句
verse = soup.select(".conview_main")
#将古诗分别存入data_list列表中
for iLoop in range(len(subject)):
data_list = [] #用于存储一首诗的数据
data_list.append(subject[iLoop].get_text()) #将诗的题目添加到列表中
data_list.append(dynasty_author[iLoop * 3].get_text()) #将朝代添加到列表中
data_list.append(dynasty_author[iLoop * 3 + 1].get_text()) #将作者添加到列表中
data_list.append(verse[iLoop].get_text()) #将诗句添加到列表中
data_lists.append(data_list) #将一首诗的数据添加到大列表中
return insert(data_lists)
#插入数据库h
def insert(data):
global count
for row in data:
count += 1
row.insert(0, count) #在头部添加一个数据作为ID
print(count,end=':')
obj.insert("tangshi","(ID,name,dynasty,author,verse)",str(tuple(row)))
if __name__ == '__main__':
# 调用数据库连接类
obj = ConnectMysql('localhost', 3306, 'root', '11111111')
# 调用数据库连接方法
obj.connectsql()
#创建数据库
obj.create_database("tangshi300")
#使用数据库
obj.use_database("tangshi300")
#创建表
obj.create_table(
"tangshi",
"(ID int primary key,name varchar(25),dynasty varchar(2),author varchar(10),verse text)"
)
count = 0 # 统计诗的数量
#循环调用
for iLoop in range(21):
#调用get_html函数
get_html(iLoop)
#关闭连接和游标
obj.close_all()
verse text)"
)
count = 0 # 统计诗的数量
#循环调用
for iLoop in range(21):
#调用get_html函数
get_html(iLoop)
#关闭连接和游标
obj.close_all()