python爬虫入门

    科技2022-08-14  92

    爬虫能干什么呢?一句话概括,正常通过浏览器可以获取的数据,爬虫都可以获取。这句话可以说是包罗万象。一是说明了爬虫的本质是一个服务端,实现的功能类似于浏览器;二是说明了爬虫的界限,如果不能正常访问到的数据就不能通过爬虫获取;三是爬虫的最高境界,只要是浏览器能正常访问的都可以用爬虫获取。

    爬虫:我们需要干的事情其实就两件事情:找到我们需要的网页,然后把他们一个一个处理一遍。一,怎么找到我们需要的网页的那个入口?二,怎么处理我们需要处理的网页?

    爬虫的核心模块有三个:请求、解析、储存。

    请求

    我们先使用requests包。这是一个第三方模块,对HTTP协议进行了高度封装,非常好用。HTTP协议:简单地说就是一个请求过程。服务器响应并返回相应数据,我们要实现的目的是把网页请求(或者说下载)下来。

    安装requests

    pip install requests

    导入requests

    import requests

    调用requests的get函数,把网页请求下来

    r = requests.get('www.baidu.com')

    输出请求下来的网页格式

    print(r.text)

    requests的一些属性

    >>> import requests >>> r = requests.get("http://www.baidu.com") >>> r.status_code 200 >>> r.endcoding = 'utf-8' >>> r.text

    requests异常问题

    requests的一些方法

    一些小实例

    # 实例1: import requests url = "https://item.jd.com/1350837.html" try: r = requests.get(url) r.raise_for_status() r.encoding = r.apparent_encoding print(r.text[:1000]) except: print("爬取失败") #实例2 搜索引擎关键字搜索 import requests r = requests.get(url='http://www.itwhy.org') # 最基本的GET请求 print(r.status_code) # 获取返回状态 r = requests.get(url='http://dict.baidu.com/s', params={'wd':'python'}) #带参数的GET请求 #params为url中的额外参数,字典或字节流格式 print(r.url) print(r.text) #打印解码后的返回数据 #ip地址查询 #www.ip138.com import requests url = "http://m.ip138.com/ip.asp?ip=" try: r = requests.get(url+'210.40.17.226') r.raise_for_status() r.encoding = r.apparent_encoding print(r.text[-500:]) except: print("爬取失败") #用来页面验证、人机交互 解析

    requests包可以使用http协议获取相应的网页文件,但是往往请求下来的是整个页面的代码,这样的信息太多了,从这一大坨代码里面找信息太麻烦了。我们需要另一个库来解析文件:BeautifulSoup4(bs4)

    bs4安装:

    pip install beautifulsoup4

    bs4是一个非常好的解析网页的库。这次的解析先给大家看bs4里面最常用的几个BeautifulSoup对象的方。我们使用的这几个方法,主要是通过HTML的标签和标签里面的参数来定位,然后用特定方法提取数据。

    beautifulsoup的简单使用:

    form bs4 import BeautifulSoup ...... soup = BeautifulSoup(html,'html.parser') #html.parser是解析器 #还有 lxml的html lxml的xml html5lib 解析器 #<p>data</P>可以替换成其他的html属性

    测试链接:https://python123.io/ws/demo.html

    点击进入

    测试这个网页:

    import requests r = requests.get('https://python123.io/ws/demo.html') print(r.text)

    返回信息:

    <html> <head> <title>This is a python demo page </title> </head> <body> <p class="title"><b>The demo python introduces several python courses.</b></p> <p class="course">Python is a wonderful general-purpose programming language. You can learn Python from novice to professional by tracking the following courses: <a href="http://www.icourse163.org/course/BIT-268001" class="py1" id="link1">Basic Python</a> and <a href="http://www.icourse163.org/course/BIT-1001870001" class="py2" id="link2">Advanced Python</a>.</p> </body> </html>

    开始解析:

    import requests from bs4 import BeautifulSoup r = requests.get('https://python123.io/ws/demo.html') demo = r.text soup = BeautifulSoup(demo,"html.parser") #soup2 = BeautifulSoup(open("D://demo.html"),"html.parser") print(soup.prettify())

    理解:

    #html文件的大概框架 <html> <body> <div class="abc"></div> <p class="bcd"></p> #标签格式<p></p> 此处标签name就是p,class="bcd"是属性域,键值对构成 </body> b</html> #BeautifulSoup是解析、遍历、维护、“标签书”的功能库

    BeautifulSoup类的基本元素

    1.Tag:标签。最基本的信息组织单元,<>、</>开头和结尾

    2.Name:标签的名字,格式:< tag>.name

    3.Attributes:标签的属性,字典形式组织,格式< tag>.attrs

    4.NavigableString:标签内的非属性字符串,格式< tag>.string

    5.Comment:标签内字符串的注释部分,一种特殊的Comment类型

    解析1:

    import requests from bs4 import BeautifulSoup r = requests.get('https://python123.io/ws/demo.html') demo = r.text soup = BeautifulSoup(demo,"html.parser") print(soup.prettify()) print("-------------------------------") print(soup.title) print("-------------------------------") print(soup.a) print("-------------------------------") print(soup.a.name) print("-------------------------------") print(soup.a.parent.name) print("-------------------------------") print(soup.a.parent.parent.name)

    解析2:

    import requests from bs4 import BeautifulSoup r = requests.get('https://python123.io/ws/demo.html') demo = r.text soup = BeautifulSoup(demo,"html.parser") tag = soup.a print("-------------------------------") print(tag.attrs) print("-------------------------------") print(tag.attrs['class']) print("-------------------------------") print(tag.string) print("-------------------------------") print(soup.p.string)

    解析3:

    3种遍历方式:

    1.下行遍历:

    .contents:子节点的列表,将< tag>所有的儿子节点存入列表 .childen:子节点的迭代类型,与.contents类似,用于循环遍历儿子节点 .desendants:子孙节点的迭代类型,包括所有的子孙节点,用于循环遍历 import requests from bs4 import BeautifulSoup r = requests.get('https://python123.io/ws/demo.html') demo = r.text soup = BeautifulSoup(demo,"html.parser") print("-------------------------------") print(soup.head) print("-------------------------------") print(soup.head.contents) print("-------------------------------") print(soup.body.contents) print("-------------------------------") print(len(soup.body.contents)) #获得body儿子节点的数量(个数) print("-------------------------------") print(soup.body.contents[1]) #因为存放的方式为列表,可以用列表下表的方式获取 print("-------------------------------") for child in soup.body.children: #遍历儿子节点 print(child) print("--")

    2.上行遍历:

    .parent:节点的父亲标签 .parents:节点先辈标签的迭代类型,用于循环遍历先辈节点 import requests from bs4 import BeautifulSoup r = requests.get('https://python123.io/ws/demo.html') demo = r.text soup = BeautifulSoup(demo,"html.parser") print("-------------------------------") print(soup.head) print("-------------------------------") print(soup.head.parent) print("-------------------------------") for parent in soup.a.parents: #上行遍历 if parent is None: print(parent) else: print(parent.name)

    3.平行遍历:

    .next_sibling:返回下一个平行节点 .previous_sibling:返回上一个平行节点 .next_siblings:返回后续的所有平行节点 .previous_siblings:返回前序的所有平行节点

    实战小项目:

    #爬取中国大学排名 import requests from bs4 import BeautifulSoup import bs4 def getHTMLText(url): try: r = requests.get(url, timeout=30) r.raise_for_status() r.encoding = r.apparent_encoding return r.text except: return "" def fillUnivList(ulist, html): soup = BeautifulSoup(html, "html.parser") for tr in soup.find('tbody').children: if isinstance(tr, bs4.element.Tag): tds = tr('td') ulist.append([tds[0].string, tds[1].string, tds[3].string]) def printUnivList(ulist, num): print("{:^10}\t{:^6}\t{:^10}".format("排名","学校名称","总分")) for i in range(num): u=ulist[i] print("{:^10}\t{:^6}\t{:^10}".format(u[0],u[1],u[2])) def main(): uinfo = [] url = 'http://www.zuihaodaxue.com/zuihaodaxuepaiming2019.html' html = getHTMLText(url) fillUnivList(uinfo, html) printUnivList(uinfo, 100) # 100 univs main() #一周天气 import csv import urllib.request from bs4 import BeautifulSoup url = "http://www.weather.com.cn/weather/101270101.shtml" header = ("User-Agent","Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/69.0.3497.100 Safari/537.36") # 设置头部信息 opener = urllib.request.build_opener() # 修改头部信息 opener.addheaders = [header] #修改头部信息 request = urllib.request.Request(url) # 制作请求 response = urllib.request.urlopen(request) # 得到请求的应答包 html = response.read() #将应答包里面的内容读取出来 html = html.decode('utf-8') # 使用utf-8进行编码,不重新编码就会成乱码 final = [] #初始化一个空的list,我们为将最终的的数据保存到list bs = BeautifulSoup(html,"html.parser") # 创建BeautifulSoup对象 body = bs.body # 获取body部分 data = body.find('div',{'id':'7d'}) # 找到id为7d的div ul = data.find('ul') # 获取ul部分 li = ul.find_all('li') # 获取所有的li # print (li) i = 0 for day in li: # 对每个li标签中的内容进行遍历 if i < 7: temp = [] date = day.find('h1').string # 找到日期 # print (date) temp.append(date) # 添加到temp中 # print (temp) inf = day.find_all('p') # 找到li中的所有p标签 # print(inf) # print (inf[0]) temp.append(inf[0].string) # 第一个p标签中的内容(天气状况)加到temp中 if inf[1].find('span') is None: temperature_highest = None # 天气预报可能没有当天的最高气温(到了傍晚,就是这样),需要加个判断语句,来输出最低气温 else: temperature_highest = inf[1].find('span').string # 找到最高温度 temperature_highest = temperature_highest.replace('℃', '') # 到了晚上网站会变,最高温度后面也有个℃ temperature_lowest = inf[1].find('i').string #找到最低温度 temperature_lowest = temperature_lowest.replace('℃', '') # # 最低温度后面有个℃,去掉这个符号 temp.append(temperature_highest) temp.append(temperature_lowest) final.append(temp) i = i +1 # print(final) with open('weather.csv', 'a', errors='ignore', newline='') as f: f_csv = csv.writer(f) f_csv.writerows(final)
    Processed: 0.012, SQL: 8