关于初学python的一点问题总结(一)

来源:互联网 发布:阿里云上海公司地址 编辑:程序博客网 时间:2024/05/16 19:30

关于初学python的一点问题总结(一)

目录

  • 关于初学python的一点问题总结一
    • 目录
    • 总结
      • 页面抓取
      • 开始使用BeautifulSoup
      • 根据标签属性抽取数据
      • 正则表达式
      • 开始过滤单个页面获取信息
      • 开始抓取内部链接数据
      • 最后说点


总结

这几天看了一下《python网络数据采集》,跟着书上差不多看了前面三章然后完成了一点书上的代码,这本书都是基于3.0以上的版本在写的,中间插入scrapy框架又需要用2.7版本。

页面抓取

首先是对整个html页面的抓取:

from urllib.request import urlopenhtml=urlopen("http://baike.baidu.com")print(html.read())

这个样子基本就可以拿下网页的html并输出到控制台上。

开始使用BeautifulSoup

通过python3中自带的pip程序(程序在\Python\Scripts),在cmd中运行,如图所示:

添加bs4

添加之后进行引用,然后就可以对页面DOM树直接进行操作,代码如下:

from bs4 import BeautifulSoupfrom urllib.request import urlopenhtml=urlopen("http://baike.baidu.com")bsObj=BeautifulSoup(html.read(), "html.parser")print(bsObj.title)

根据标签属性抽取数据

在BeautifulSoup的对象当中,通过find()和findAll()方法查询,产生Tag对象。然后使用Tag.get_text()就可以输出标签内容。具体的方法如下:

bsObj.findAll("div",{"class":"content"})bsObj.findAll(class_="content")

对于兄弟,父母或者子标签,分别有对应的方法使用:.next_siblings() .parent 以及 .children

正则表达式

在某些标签的筛选中,可以使用正则表达式对特定的字符串进行筛选。这里有一个测试正则表达式的网站:RegexPal
关于正则表达式,具体的内容不再阐述,很多博客都有讲解。

开始过滤单个页面获取信息

首先通过遍历百度百科某个页面,结合正则表达式,并获取其中指向内部的<a>标签

from bs4 import BeautifulSoupfrom urllib.request import urlopenimport rehtml=urlopen("http://baike.baidu.com/item/%E8%B5%B5%E6%B0%8F%E5%AD%A4%E5%84%BF/13828701")bsObj=BeautifulSoup(html.read(), "html.parser")btnList=bsObj.find("div",{"class":"body-wrapper"}).findAll("a",href=re.compile("^(/item/|/view/)"))for btn in btnList:    if 'href' in btn.attrs:        print(btn.get_text())        print(btn.attrs['href'])

输出结果如下:
这里写图片描述

开始抓取内部链接数据

接下来就是开始对整个百度百科进行抓取,并将抓取内容输出到txt文件里面。代码如下:

# -*- coding: utf-8 -*-import sysfrom urllib.request import urlopenfrom bs4 import BeautifulSoupimport datetimeimport randomimport re# sys.setdefaultencoding('utf-8')def getLinks(aUrl):    global pages    html=urlopen("http://baike.baidu.com"+aUrl)    bsObj=BeautifulSoup(html.read(),"html.parser")    links=bsObj.find("div",{"class":"body-wrapper"}).findAll("a",href=re.compile("^(/item/|/view/)"))    urlcontent=bsObj.find("div",{"class":"para"}).get_text()+"\n"    print("content:"+urlcontent)    f=open("baike.txt","a+",encoding='utf-8')    f.write(urlcontent)    for link in links:#开始抽取<a>标签的属性        if 'href' in link.attrs:            if link.attrs['href'] not in pages:                list=link.get_text()+" "+link.attrs['href']+"\n"                print(list)                f.write(list)                pages.add(link)        if link.attrs['href']=="/view/10812319.htm":#如果跳转到死链接就将链接初始化            link.attrs['href']="/item/%E6%95%B0%E6%8D%AE%E6%8C%96%E6%8E%98"    f.close()    return linksrandom.seed(datetime.datetime.now())pages=set()links=getLinks("/item/%E6%95%B0%E6%8D%AE%E6%8C%96%E6%8E%98")while len(links)>0:    newArt=links[random.randint(0,len(links)-1)]    newArthref=newArt.attrs['href']    newArttitle=newArt.get_text()    result='----->'+newArttitle+' '+newArthref+"\n"    print("==============")    print(result)    f=open("baike.txt","a+",encoding='utf-8')    f.write(result)    f.close()    print("==============")    links=getLinks(newArthref)

整个代码将会开始进行一个死循环,然后开始持续抓取数据,然后将抓取的内部链接写进文本中。

最后说点

代码中间会产生重复的数据,将会在下次更新博客的时候解决。
写入文件时候的编码问题,在写入txt的时候,默认的txt文件编码为ANSI,需要先把txt的编码改变为utf-8,才能写入,否则会出现乱码。
内存溢出问题,在持续循环的时候,由于访问页面的增加,其中的request和response对象会直接存放在内存当中,这样会造成内存溢出,解决方案留在下次更新。

0 0
原创粉丝点击