xpath的路径表达式:
表达式 | 描述 |
---|---|
nodename | 选取此名字节点的所有子节点。 |
/ | 从根节点选取。 |
// | 选取其后节点的所有子元素,而不考虑它们的位置。 |
. | 选取当前节点。 |
… | 选取当前节点的父节点。 |
@ | 选取属性。 |
* | 匹配任何元素节点 |
@* | 匹配任何属性节点。 |
nodename/text() | 选取当前节点的所有文本子节点。 |
| | 返回两个xpath表达式的结果 |
路径表达
- 绝对位置路径:
/step/step/… - 相对位置路径:
step/step/…
1. 从https://www.ucas.ac.cn/网站上抓取:学校概况、组织机构等名称,包括该名称下的目录名称。
#coding:utf-8
from lxml import etree
import urllib.request
# 1.获得网页内容
url = "https://www.ucas.ac.cn/"# 所要爬取的目标网址
req = urllib.request.Request(url=url)
req.add_header("User-Agent","Mozilla/5.0 (Windows NT 10.0; Win64; x64)AppleWebKit/537.36 (KHTML, like Gecko) Chrome/81.0.4044.92 Safari/537.36")# 伪装浏览器用户代理
webPage = urllib.request.urlopen(req).read().decode('utf-8')# 缓存网页并转化编码
# print(webPage)# 测试网页是否已经缓存
# 2. 使用xpath进行网页内容的分解和抓取
content = etree.HTML(webPage) # 将HTML字符格式转化为_Element对象,方便使用xpath的函数方法
rows = content.xpath('//*[@id="nav"]')# 选择所有id名称为menu的标签
for row in rows:
situation = row.xpath('li[1]/a/text() | li[1]/ul/li/a/text()')
organation = row.xpath('li[2]/a/text() | li[2]/ul/li/a/text()')
faculty = row.xpath('li[3]/a/text() | li[3]/ul/li/a/text()') # faculy能力
education = row.xpath('li[4]/a/text() | li[4]/ul/li/a/text()')
research = row.xpath('li[5]/a/text() | li[5]/ul/li/a/text()')
employment = row.xpath('li[6]/a/text() | li[6]/ul/li/a/text()')
information = row.xpath('li[7]/a/text() | li[7]/ul/li/a/text()')
life = row.xpath('li[8]/a/text() | li[8]/ul/li/a/text()')
print(situation)
print(organation)
print(faculty)
print(education)
print(research)
print(employment)
print(information)
print(life)
'''
//*[@id="mainlevel_07"]/a
审查元素-右击元素代码-Copy-CopyXPath
'''
2. 人民邮电出版社推荐书下载
要求
- 抓取每个学科下的推荐书,书名以及价格
- 使用: requests
- 结果保存到数据库中
import requests
import json
import time
import mysql.connector
# 获取url的内容并转化为字符串
def url_to_meg(url):
subjct_type = requests.request('GET', url, headers=headers) # 爬取每个专业信息
typeJson = json.loads(subjct_type.text) # 将字符串转化为字典类型
return typeJson
# 进行数据库的插入操作
def insert_sql(sql):
cur = db.cursor() # 创建游标
sql = 'insert into book_spider(field, book_title, book_price) values("%s", "%s", %f)' % (
book_name, bookName, bookPrice)
cur.execute(sql)
db.commit()
cur.close()
db.close()
# 动态网页是通过上一个页面的头文件发起请求的,与单独请求不同,否则不响应
headers = {
"Connection": "keep-alive",
"Sec-Ch-Ua": "\"Microsoft Edge\";v=\"93\", \" Not;A Brand\";v=\"99\", \"Chromium\";v=\"93\"",
"Accept": "application/json, text/javascript, */*; q=0.01",
"X-Requested-With": "XMLHttpRequest",
"Sec-Ch-Ua-Mobile": "?0",
"User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/93.0.4577.63 Safari/537.36 Edg/93.0.961.47",
"Sec-Ch-Ua-Platform": "\"Windows\"",
"Sec-Fetch-Site": "same-origin",
"Sec-Fetch-Mode": "cors",
"Sec-Fetch-Dest": "empty",
"Referer": "https://www.ptpress.com.cn/shopping/index",
"Accept-Language": "zh-CN,zh;q=0.9,en;q=0.8,en-GB;q=0.7,en-US;q=0.6"
}
# 存储了每个专业的url
decipline_url = 'https://www.ptpress.com.cn/hotBook/getParentTagIdList'
# 决定是否写入数据库
if __name__ == '__main__':
typeJson = url_to_meg(decipline_url)
typeJson=typeJson['data'] # 消除data前缀
print(typeJson)
db = mysql.connector.connect(# 打开数据库
host="localhost",
user="root",
password="2",
database="py_spider"
)
# 遍历书籍信息,写入数据库
for decline_id in typeJson:
book_list = "https://www.ptpress.com.cn/hotBook/getHotBookList?parentTagId="+ decline_id['PARENTTAGID'] + "&rows=18&page=1" # 找到专业下面的书的目录
book_data = url_to_meg(book_list) # 获取每个学科链接下的书名json
book_data = book_data['data']['rows'] # 简化无用的键
# 删除列表中嵌套的字典
for book_name in book_data:
# 写入数据库部分
cur = db.cursor() # 创建游标
sql = 'insert ignore into people_book(book_name, price, discountPrice) values("%s", "%s", %f)' % ( # insert ignore可以忽略重复的主键
book_name['bookName'], float(book_name['price']), float(book_name['discountPrice']))
cur.execute(sql)# 执行sql语句
db.commit()# 提交到数据库执行
'''可把数据库部分注释掉,以下部分可以进行测试用
print(book_name['bookName'])
print(book_name['price'])
print(book_name['discountPrice'])
'''
cur.close()
db.close()
'''
列表[ ]里面可以存放:数字、字符串、列表、布尔值,可以嵌套任意类型
字典类型{ A:'B' ,A2:'C' },内部由键值对构成,键是唯一的
'''
successful
总结: