1 问题描述
在CSDN站内搜索技术关键词,例如java,下载前几页热门文章HTML源码到本地,文件命名方
式与博客大标题保持一致
2 解题提示
本周录播课最后两节
3 评分标准
- 本题共计40分
- 破解URL规则,通过Xpath得到链接地址与博客标题20分
- 完成博客下载 10分
- 代码注释,规范10分
4 要点解析
4.1 防爬机制
- 请求头
- 模仿浏览器进行访问
- 代理ip
- 加代理,通过换ip地址
- cookie
- 有些网站是需要登录才可以的,所以可以获取cookie
5 实现步骤
- 有代理
import urllib.request as ur
import lxml.etree as le
import user_agent
keyword = input('请输入关键词:')
pn_start = int(input('起始页:'))
pn_end = int(input('终止页:'))
def getRequest(url):
return ur.Request(
url=url,
headers={
'User-Agent':user_agent.get_user_agent_pc(),
}
)
# 代理ip
def getProxyOpener():
# 代理ip地址
proxy_address = ur.urlopen('http://api.ip.data5u.com/dynamic/get.html?order=b302473c7d3fb594860238e20a651296&sep=3').read().decode('utf-8').strip()
# 给请求加上代理
proxy_handler = ur.ProxyHandler(
{
'http':proxy_address
}
)
# 返回加上代理之后的请求
return ur.build_opener(proxy_handler)
for pn in range(pn_start,pn_end+1):
request = getRequest(
'https://so.csdn.net/so/search/s.do?p=%s&q=%s&t=blog&domain=&o=&s=&u=&l=&f=&rbg=0' % (pn,keyword.encode('utf-8'))
)
try:
# 传递请求获得响应
response = getProxyOpener().open(request).read()
href_s=le.HTML(response).xpath('//div[@class="limit_width"]/a/@href')
for href in href_s:
try:
response_blog = getProxyOpener().open(
getRequest(href)
).read()
title = le.HTML(response_blog).xpath('//h1[@class="title-article"]/text()')[0]
# count=le.HTML(response_blog).xpath('//span[@class="mr16"]/text()')
print(title)
with open('blog/%s.html' % title,'wb') as f:
f.write(response_blog)
except:
print('爬取失败!')
except:pass
- 代理
import urllib.request as ur
import lxml.etree as le
import user_agent
keyword = input('请输入关键词:')
pn_start = int(input('起始页:'))
pn_end = int(input('终止页:'))
# 请求函数
def getRequest(url):
return ur.Request(
url=url,
headers={
'User-Agent':user_agent.get_user_agent_pc(),
}
)
for pn in range(pn_start,pn_end+1):
# 调用请求函数,获得响应
request = getRequest(
'https://so.csdn.net/so/search/s.do?p=%s&q=%s&t=blog&domain=&o=&s=&u=&l=&f=&rbg=0' % (pn,keyword.encode('utf-8'))
)
try:
# 读取响应内容
response = ur.urlopen(request).read()
# 转化 xml,并进行xpath,获取文章链接
href_s=le.HTML(response).xpath('//div[@class="limit_width"]/a/@href')
# 遍历div
for href in href_s:
try:
# 通过获取的文章链接,进入页面
response_blog = ur.urlopen(
getRequest(href)
).read()
# 获取标题
title = le.HTML(response_blog).xpath('//h1[@class="title-article"]/text()')[0]
# count=le.HTML(response_blog).xpath('//span[@class="mr16"]/text()')
print(title)
# 保存页面
with open('blog/%s.html' % title,'wb') as f:
f.write(response_blog)
except:
print('爬取失败!')
except:pass