网络爬虫,用一句话简单总结,就是一种按照一定的规则,自动的抓取万维网信息的程序或者脚本。写这篇文章的初衷是有个知友私信我说,模仿了很多网上用Python写爬虫的例子,但到了需要自己动手写爬虫的时候又不知道怎么写了。我觉得出现这种情况还是很正常的,至少我个人是这么过来的。这篇文章仅供初学者写爬虫程序时作为一个参考,毕竟本人已经很久没写过爬虫程序了,但爬虫程序的大体框架我还是很清晰的,此篇展示的是我对爬虫的一些理解。之前写过的一些爬虫程序PythonCrawler,有兴趣的朋友可以看看,找找自信这些代码现在看来写的确实挺烂的 。
写爬虫遵循的基本框架
我自己在写爬虫时一般基本遵循下面的框架形式,按照这个框架来编写代码。
演示实例
通过对[ONE]这个网站的爬取来演示上述模块的编写,ONE网站的内容展示如下图所示。
而数据我只爬取一张图片和一句箴言,备注(该演示远非最佳实践,只是为了演示框架流程)。
- url调度模块编写
通过对ONE网站的分析,发现它的翻页就是在url后面的数字上加一进入下一页。
ROOT_URL = "http://wufazhuce.com/one/"
URL_NUM = 14 #14页之后才开始有数据def yield_url(ROOT_URL, URL_NUM):return ROOT_URL + str(URL_NUM)
- 网页下载模块编写
import requests as rqdef get_html(url):return rq.get(url).content.decode("utf-8")
- 数据抽取模块编写
通过对图片和箴言查看元素可知相关代码镶嵌情况。
因此可以编写数据抽取模块
import redef get_data(html):img_url_regex = re.compile('<img src="(.*?)" alt="" />')cite_regex = re.compile('<div class="one-cita">(.*?)</div>', re.S)img_url = re.findall(img_url_regex, html)[0]cite = re.findall(cite_regex, html)[0].strip()return img_url, cite
- 数据存储模块编写
def save_data(img_url, cite, URL_NUM):with open("./{}.jpg".format(URL_NUM), "wb") as fp:fp.write(rq.get(img_url).content)with open("./cite{}.txt".format(URL_NUM), "w") as fp:fp.write(cite)return URL_NUM + 1
整合所有模块输出爬取结果
import re
import requests as rqROOT_URL = "http://wufazhuce.com/one/"
URL_NUM = 14def yield_url(ROOT_URL, URL_NUM):return ROOT_URL + str(URL_NUM)def get_html(url):return rq.get(url).content.decode("utf-8")def get_data(html):img_url_regex = re.compile('<img src="(.*?)" alt="" />')cite_regex = re.compile('<div class="one-cita">(.*?)</div>', re.S)img_url = re.findall(img_url_regex, html)[0]cite = re.findall(cite_regex, html)[0].strip()return img_url, cite def save_data(img_url, cite, URL_NUM):with open("./{}.jpg".format(URL_NUM), "wb") as fp:fp.write(rq.get(img_url).content)with open("./cite{}.txt".format(URL_NUM), "w") as fp:fp.write(cite)return URL_NUM + 1def main(ROOT_URL, URL_NUM, number):for _ in range(number):url = yield_url(ROOT_URL, URL_NUM)html = get_html(url) img_url, cite = get_data(html) URL_NUM = save_data(img_url, cite, URL_NUM)if __name__ == "__main__":try:main(ROOT_URL, URL_NUM, 20)except:pass
结果展示:
总结✨
本文的目的只是为了让初学者对写爬虫的大体流程有较为清晰的了解。天高任鸟飞,海阔凭鱼跃!每个人心中的爬虫框架(流程)各异,实现方法各异自由发挥空间极大,但有一点务必注意那就是遵守中华人民共和国的法律。