前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Python 3.7 + BeautifulSoup 简单爬虫实例

Python 3.7 + BeautifulSoup 简单爬虫实例

作者头像
muntainyang
发布2020-10-23 11:25:39
6610
发布2020-10-23 11:25:39
举报
文章被收录于专栏:IT测试前沿

粗略的啃完requests库的官方中文文档和BeautifulSoup的文档,本期主要灵活运用相关知识,实现对freebuf.com文章信息的抓取分析。

一.分析

打开Freebuf,访问WEB安全专栏,查看其源代码,发现想要的信息——文章名,作者,文章地址,简介,访问次数以及发布时间。

一个自然而然的想法就是利用requests库抓取源代码,利用BeautifulSoup库分离出想要的信息,最后把信息保存在本地。然后把按照这个思路写下了代码。

二.实现

首先我们需要先构建request请求,由于一般网站都有反爬虫机制,所以在这里加入请求头,延迟时间。并做对于请求异常做处理。

代码语言:javascript
复制
def get_html(url, data = None):
    header = {
        'Accept': 'text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8',
        'Accept-Encoding': 'gzip, deflate, br',
        'Accept-Language': 'zh-CN,zh;q=0.9,en;q=0.8,zh-TW;q=0.7',
        'User-Agent': 'Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/68.0.3440.84 Safari/537.36'
    }
    timeout = random.choice(range(80, 100))
    while True:
        try:
            response = requests.get(url, headers=header, timeout=timeout)
            response.encoding = 'utf-8'
            break
        except socket.timeout as e:
            print(e)
            time.sleep(random.choice(range(20, 60)))
        except socket.error as e:
            print(e)
            time.sleep(random.choice(range(0, 60)))
        except http.client.BadStatusLine as e:
            print(e)
            time.sleep(random.choice(range(30, 60)))
        except http.client.IncompleteRead as e:
            print(e)
            time.sleep(random.choice(range(20, 60)))
    return response.text

请求以后,我们得到了网页数据。接下来开始利用BeautifulSoup库分离出想要的信息。可以看到,由于结构不是很复杂,而且元素没有缺失。这里我使用一个For循环的方式把它依次放到字典里。然后再添加到列表。

代码语言:javascript
复制
def get_data(html_text):
    result = []
    bs = BeautifulSoup(html_text, "html.parser")
    titles = bs.select('#timeline > div > div.news-info > dl > dt > a')
    urls = bs.select('#timeline > div > div.news-info > dl > dt > a')
    descs = bs.select('#timeline > div > div.news-info > dl > dd.text')
    writers = bs.select('#timeline > div > div.news-info > dl > dd:nth-child(2) > span.name > a')
    pvs = bs.select('#timeline > div > div.news-info > div > span.look > strong:nth-child(1)')
    uptimes = bs.select('#timeline > div > div.news-info > dl > dd:nth-child(2) > span.time')
    for title,writer,url,desc,pv,uptime in zip(titles,writers,urls,descs,pvs,uptimes):
        data = {
            'title': title.get_text(),
            'writer': writer.get_text(),
            'url': url.get('href'),
            'desc': desc.get_text(),
            'pv': pv.get_text(),
            'uptime': uptime.get_text()
        }
        result.append(data)
    return result

鉴于刚刚已经对数据做了依次处理,列表中每个字典都是一条按照正确格式排列的文章信息,接下来我们开始构建代码,把整理好的数据保存到本地。

代码语言:javascript
复制
def data_output(info, filename):
    with open(filename,'a',errors='ignore', newline='') as f:
        f_csv = csv.writer(f)
        for i in range(0,16):
            temp = [[info[i]['title']],[info[i]['writer']],[info[i]['url']],[info[i]['desc']],[info[i]['pv']],[info[i]['uptime']]]
            f_csv.writerow(temp)

按照最开始的思路(request请求->BeautifulSoup拆解->保存到本地),已经初步完成。接下构建主函数来调用。

代码语言:javascript
复制
if __name__ == '__main__':
    for num in range(1, 3):
        url = 'https://www.freebuf.com/articles/web/page/' + str(num)
        html_text = get_html(url)
        result = get_data(html_text)
        data_output(result, 'freebuf.csv')

成果图

三.总结

  • 提纲挈领。自己用了才会熟练,纸上得来终觉浅!之前啃完整的文档,并记下笔记,现在具体细节全忘了。其实本来只需要知道这个库能干什么就行了,看看例程几乎就能实现功能。
  • 戒骄戒躁。以为能直接一口气写完,找几个语法错误就over。然而到最后还是一个一个函数拿出来看看有没有错误。所以,切记!先测试好一个函数,再写下一个。
  • 未雨绸缪。一定要意识到try,except的重要性,不偷懒,多写几个,一定能在第一时间内找到错误原因。
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2019-10-21,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 IT测试前沿 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 一.分析
  • 三.总结
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档