模块三 第一周 作业三 热门文章

1 问题描述

在CSDN站内搜索技术关键词,例如java,下载前几页热门文章HTML源码到本地,文件命名方

式与博客大标题保持一致

模块三 第一周  作业三  热门文章

2 解题提示

本周录播课最后两节

3 评分标准

  1. 本题共计40分
  2. 破解URL规则,通过Xpath得到链接地址与博客标题20分
  3. 完成博客下载 10分
  4. 代码注释,规范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
上一篇:引用:编程题01


下一篇:03 PN与二极管的特性