在这里不进行多余的赘述,直接附上大佬比较详细的方法链接~
https://www.jianshu.com/p/011abdcee7e4
作者:终可见
来源:简书
看了前面的同学~这里附上爬取的完整代码。
# 导包
import requests
from pyquery import PyQuery as pq
import time # 延迟获取
# 给请求指定一个请求头来模拟chrome浏览器
# headers = {'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/54.0.2840.99 Safari/537.36'}
n = 0
'''
定义一个可以获取页面数据以及提取网页源码的函数
定义一个可以获取href属性值的函数
定义一个可以查找指定元素并提取文本内容的函数
'''
def get_html(url):
# 获取页面内容)(获取数据)
r = requests.get(url)
# 提取网页源代码
html = r.text
if r.status_code == 200:
return html
else:
return "error"
def get_attr(html, sel, attr_name):
# 使用pyquery解析网页,生成pyquery对象
doc = pq(html)
link = doc(sel)
# 找到href属性值
thunder_link = link.attr(attr_name)
return thunder_link
# 固定链接
def get_text(html, sel):
doc = pq(html)
# 4. 使用选择器在pyquery中找到指定的元素
t = doc(sel)
# 5. 在找到元素中,提取文本内容
title = t.text()
return title
# 以写入的模式打开一个名data的html文件,编码格式为utf-8
html_file = open('data.html', 'w', encoding="utf-8")
txt_file = open('data.txt', 'w', encoding="utf-8")
# 写入网页格式以及需要采集的信息,采用了bootstrap的css样式
html_file.write("""
<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>热门小说推荐</title>
<link href="https://cdn.bootcss.com/bootstrap/4.0.0/css/bootstrap.min.css" rel="stylesheet">
</head>
<body>
<h2 class="text-center">热门小说推荐</h2>
<table class="table table-striped table-hover mx-auto text-center">
<thead>
<tr>
<th>封面</th>
<th>书名</th>
<th>试读链接</th>
<th>简介</th>
</tr>
</thead>
<tbody>
""")
# url固定的部分
url = "https://xs.sogou.com/0_0_0_0_heat/?pageNo="
for i in range(1, 6):
# 字符串拼接
url_new = url + str(i)
html_list = get_html(url_new)
for j in range(1, 19):
sel = "body > div.wrapper > div.box-center.sx-wp.clear > div.sx-ret.fr > ul > li:nth-child("+str(j)+") > div > h3 > a"
# 找到指定元素
href_link = get_attr(html_list, sel, "href")
# 获取页面链接
url_detail = "https://xs.sogou.com"+href_link
# 获取页面内容
html = get_html(url_detail)
n += 1
# 找到指定元素获取内容
doc = pq(html)
# 找到试读链接在网页中的位置
items = doc('.wrapper .box-center .info-box .infos .btns').items()
# 采用字典的遍历找到试读的链接
for item in items:
xia = {
'xiazai': "https://xs.sogou.com"+item.find('a').attr('href'),
'shidu': item.find('a').attr('pbtag')
}
# 将找到的“免费试读”四个字命名为shidu
shidu = xia['shidu']
# 将找到的试读链接命名为url_xiazai
url_xiazai = xia['xiazai']
# 获取作者名称
zuozhe = get_text(html, "body > div.wrapper > div.box-center.intro-wp.clear > div.intro-main.fl > div.info-box.clear > div > div.field.clear > span:nth-child(1)")
# 获取小说名称
title = get_text(html, "body > div.wrapper > div.box-center.intro-wp.clear > div.intro-main.fl > div.info-box.clear > div > h1")
# print(title)
# 获取小说已有字数
zishu = get_text(html, "body > div.wrapper > div.box-center.intro-wp.clear > div.intro-main.fl > div.info-box.clear > div > div.field.clear > span:nth-child(4)")
# print(zishu)
# 获取小说类型
leixing = get_text(html, "body > div.wrapper > div.box-center.intro-wp.clear > div.intro-main.fl > div.info-box.clear > div > div.field.clear > span:nth-child(2)")
# print(leixing)
# 获取小说简介
jianjie = get_text(html, "body > div.wrapper > div.box-center.intro-wp.clear > div.intro-main.fl > div.info-box.clear > div > div.desc.desc-long.hide")
# 这里因为各个小说中简介的长短不同因此简介的标签有所差别用了一个if进行判断,如果找不到长简介所代表的标签就去找短简介的标签
if jianjie == '':
jianjie = get_text(html, "body > div.wrapper > div.box-center.intro-wp.clear > div.intro-main.fl > div.info-box.clear > div > div.desc.desc-short")
else:
pass
# print(jianjie)
# 打印书名,作者,字数,类型,简介以及小说链接
print('书名:{},\n{}, \n{},\n{},\n简介:{},\n链接:{}'.format(title, zuozhe, zishu, leixing, jianjie, url_detail))
txt_file.write("""
书名:{},\n{}, \n{},\n{},\n简介:{},\n链接:{}
""".format(title, zuozhe, zishu, leixing, jianjie, url_detail))
# 将html的内容填充
html_file.write("""
<tr>
<td><img src="../python/img/{}.jpg"width="45%"/></td>
<td><a href="{}">{}</a></td>
<td><a href="{}">{}</a></td>
<td>{}</td>
</tr>
""".format(n, url_detail, title, url_xiazai, shidu, jianjie))
# python 里面三个"围起来的字符会被看做是一整个字符串,避免了换行符的麻烦。
# .format()这个方法的用法是把字符串里面的{}字符,按次序一一替换成 format() 接受的所有参数。
html_file.write("""
</tbody>
</table>
</body>
</html>
""")
# 关闭写入
html_file.close()
# 关闭写入
txt_file.close()
# 暂停8s
time.sleep(8)