从零开始的项目实战(6)——一只小爬虫

姚大炮 2020-09-21 22:13:29

按照我以往的经验,前端应该到了”切页面“的阶段,距离前后端联调估计还有不少时间。

单独的一段html或者js代码拿出来其实是没有多大意义的,想把最好的效果展示给大家可能得等上一段时间,接下来的一段时间(到大部分页面完成)就由我来陪着大家。

初次见面,我们就聊些有意思的东西--Python爬虫。

项目中用到的图片资源,一部分是后台上传的,另一部分要通过爬虫来抓取一些头像网站。

今天就看一个简单的Demo,大家一起熟悉一下。

不需要使用scrapy。requests足以满足我们的需要。

对了,我所使用的开发工具为Pycharm,在官网可以免费下载并且试用一段时间,有需要破解的同学可以在评论区留言或者直接私信我。

import sysimport requestsimport xlsxwriterfrom bs4 import BeautifulSoup

有python基础的同学应该知道这是python中的库引用(又称“导包”),我们的重点是后面三个。

1、requests(文档地址:https://requests.readthedocs.io/zh_CN/latest/):

看到这个标语,应该不需要我再多解释什么。不熟悉的同学请好好阅读文档。程序员需要具备阅读文档的能力,包括英文文档。

推荐一款软件吧,网易有道词典。有了它的截屏翻译功能,再也不需要担心自己看不懂英文文档。

支持自定义快捷键哦!

2、xlsxwriter:一个python用来构造xlsx文件的模块

怎么说了,你想实现的功能都可以在百度上找到教程,不推荐像requests库那样花精力研究。

3、BeautifulSoup主要功能:从网页抓取数据

官方解释:

Beautiful Soup提供一些简单的、python式的函数用来处理导航、搜索、修改分析树等功能。它是一个工具箱,通过解析文档为用户提供需要抓取的数据,因为简单,所以不需要多少代码就可以写出一个完整的应用程序。

Beautiful Soup自动将输入文档转换为Unicode编码,输出文档转换为utf-8编码。你不需要考虑编码方式,除非文档没有指定一个编码方式,这时,Beautiful Soup就不能自动识别编码方式了。然后,你仅仅需要说明一下原始编码方式就可以了。

Beautiful Soup已成为和lxml、html6lib一样出色的python解释器,为用户灵活地提供不同的解析策略或强劲的速度。

用它可以很方便地提取出html和XML标签中的内容,对于一些正则匹配不太熟悉的同学简直就是神器,(类似的Xpath选择器,Css选择器)

下载Pycharm、安装Python库有问题的同学可以在评论区留言或者直接私信我。

撸代码之前我先简单讲一下这个Demo的功能。

磁力狗(http://clg8.org/)这样一个种子搜索网站相信不少老司机朋友都使用过,我希望构造一个函数,我输入想搜索的内容,可以在指定位置生成一个内容与种子的excel文件。

需求分析完毕先不着急动手。

建议所有同学都可以养成这样一个习惯:动手前仔细观察一下它的URL。我在搜索框中输入了"寄生虫"与"韩国",响应页面的URL如下:

不安全是因为没有使用https,这个不是重点。

经过多次尝试,最终得到的结果:

http://clg8.org/search?word={0}&sort=rele&p={1}

word=”你在输入框中输入的内容(使用'+'连接)“

sort=rele  可能为一种排序方式

p=1   后端的分页处理

我按照我的思路讲解我的代码。

url = "http://clg8.org/search?word={0}&sort=rele&p={1}"headers = {    'User-Agent': 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.67 Safari/537.36',}key_word = ""targetData=[]

url:requests请求的接口。

headers:请求requests.get(url=targetUrl, headers=headers, params='html')使用的参数,可以直接复制我代码中的或者F12(开发者工具)从按照箭头所指的方式获取。

key_word:将输入框中输入关键词处理完存储为全局变量。

targetData:将获取到的数据存入数组,最终统一写入excel文件。

def getSource(page, *args):    if args:        for i in args:            global key_word            key_word+= i + "+"    try:        targetUrl = url.format(key_word, page)        # 返回数据        responese = requests.get(url=targetUrl, headers=headers, params='html')        responese.encoding = "utf-8"        content = responese.text        praseContent(content)    except:        s = sys.exc_info()        print("Error '%s' happened on line %d" % (s[1], s[2].tb_lineno))        return " ERROR "

不了解*args的同学,建议百度研究一下python中的 *args 与 **kwargs。

将传入的参数用“+”链接并存入全局变量(key_word)。将requests请求到的数据传入praseContent方法。

def praseContent(content):    soup = BeautifulSoup(content, features="lxml")    titles = soup.find_all(name='div',_="SearchListTitle_list_title")    for title in titles:        herf = title.find(name="a").get("href")        # 这一条数据的名称 这里可以进行数据筛选(正则等等)        title = title.find(name="a").text        # 目标页面        targetherf = "http://clg8.org/{0}".format(herf)        parseDetail(targetherf)      # 判断是不是最后一页      # 是不是有分页     if soup.find("ul",class_="pagination").find("li"):        isLastPage=soup.find("ul",class_="pagination").find("li",class_="active").nextSibling        nextNum=isLastPage.find("a").text        if nextNum!="尾页":            print("还有下一页")            getSource(nextNum)        else:            enter()            return      else:          # 只有一页         return

将传入的数据使用BeautifulSoup解构,列表页面无法获取到我们需要的磁力链接:

需要进入到详情页面:

请忽视右下角的马赛克部分。

将获取到的图片中箭头所指的 a标签的href属性值与根地址拼接就可以获取到对应的详情页面地址。获取到地址之后,将url传入parseDetail方法,进行下一步操作。

通过查找页面中的分页按钮遍历所有页面:如果没有分页按钮则数据只有一页,按钮的value值为尾页则遍历结束。

def parseDetail(url):    responese = requests.get(url=url, headers=headers, params='html')    responese.encoding = "utf-8"    content = responese.text    soup = BeautifulSoup(content, features="lxml")    titles = soup.find(name='h1',_="Information_title").text    link = soup.find(name="a",_="Information_magnet").get("href")    targetData.append({"title":titles,"link":link})

和上一步所进行的解析差不多,如果有同学对于find,find_all以及链式操作(title.find(name="a").get("href"))有疑问,请务必百度了解一下。

# 写入exceldef enter():    workbook=xlsxwriter.Workbook("../excel/{}.xlsx".format(key_word.split("+")[0]))    worksheet=workbook.add_worksheet()    # 自定义样式    bold_format=workbook.add_format({"bold":True})    # 设置第二行第二列的宽度为15    worksheet.set_column(1,1,15)    # 符号标记位置    worksheet.write("A1","名称",bold_format)    worksheet.write("B1","种子地址",bold_format)    row=1    col=0    for item in targetData:        worksheet.write_string(row,col,str(item["title"]))        worksheet.write_string(row,col+1,str(item["link"]))        row+=1    workbook.close()

创建一个xlsx文件,遍历targetData数组将数据写入创建的文件。

最终得到我们需要的xlsx文件:

做不到将知识点面面俱到,篇幅有限只能说到这里,有问题的同学可以在评论区留言或者私信我,我会尽快给出回答或者在下期文章中与大家一起探讨这些问题。

代码有很多可以改进的地方,例如根据获取到的名称进行正则判断或者异步任务提高效率,后面的文章中我会慢慢改进这些问题。

我是姚大炮,90后程序员,希望能够永远年轻永远热泪盈眶。晓看天色暮看云,行也思汝,坐亦思汝。关注小姚,和你一起看云海翻涌江潮澎湃。

0 阅读:0

姚大炮

简介:一个逗逼的程序员,爱生活,爱世界。