词云: Python爬取国际时事

前置工具

python
wordcloud
jieba
BeautifulSoup
matplotlib
scipy

第一步: 爬取国际时事列表

待爬地址: http://m.sohu.com/cr/57/?page=1&v=2

首先我们可以观察到,每点击列表中的下一页时, page 会加一

然后我们就可以确认,想获取多少条信息,直接替换page属性的值即可

然后我们观察想要爬取的内容:

审查元素:

我们发现文本都是在 div(class=”bd3 pb1″) -> div -> p -> a 标签下的:

编写代码

爬取数据并保存在data.txt中:

# coding: utf-8

from wordcloud import WordCloud
import requests
from bs4 import BeautifulSoup
import re

def getHTMLText(url):
    try:
        r = requests.get(url)
        r.raise_for_status()
        r.encoding = r.apparent_encoding
        return r.text
    except:
        pass

def has_p_a(tag):
    pass

def getWannaData(stockURL,res):
    html = getHTMLText(stockURL)
    soup = BeautifulSoup(html,'html.parser')
    p = soup.find('div',class_="bd3 pb1").find_all('a')
    for q in p:
        res.append(q.text)

res = []
maxn = 100
for i in range(1,maxn):
    getWannaData('http://m.sohu.com/cr/57/?page='+str(i)+'&v=2',res)

file = open('data.txt','a+')
for q in res:
    file.write(q+'\n')

其中maxn是控制爬取多少页的

data.txt 部分内容:

第二步: 生成词云

前置

因为要进行中文分词,所以要用jieba
注意再打开data.txt编码问题
还有ttf不能保存在有中文的路径下

背景图片

我们选择 水伊布.png

生成词云

容我说一句,在中国相对封闭的网络环境中,已经可以看到世界如此的乱了,全部的词条大部分是消极的…看起来大规模战争结束的时间太久了…(还是说,世界就没有安宁过)

这张图可以找到安倍

股票数据定向爬虫

累了…直接撩代码

import requests
from bs4 import BeautifulSoup
import traceback
import re

def getHTMLText(url):
    try:
        r=requests.get(url)
        r.raise_for_status()
        r.encoding=r.apparent_encoding
        return r.text
    except:
        return ""

def getStockList(lst,stockURL):
    html=getHTMLText(stockURL)
    soup=BeautifulSoup(html,'html.parser')
    a=soup.find_all('a')
    for i in a:
        try:
            href=i.attrs['href']
            lst.append(re.findall(r'[s][hz]\d{6}',href)[0])
        except:
            continue

def getStockInfo(lst,stockURL,fpath):
    for stock in lst:
        url=stockURL+stock+".html"
        html=getHTMLText(url)
        try:
            if html=="":
                continue
            infoDict={}
            soup=BeautifulSoup(html,'html.parser')
            stockInfo=soup.find('div',attrs={'class':'stock-bets'})

            name=stockInfo.find_all(attrs={'class':'bets-name'})[0]
            infoDict.update({'股票名称':name.text.split()[0]})
            keyList=stockInfo.find_all('dt')
            valueList=stockInfo.find_all('dd')
            for i in range(len(keyList)):
                key=keyList[i].text
                val=valueList[i].text
                infoDict[key]=val

            with open(fpath,'a',encoding='utf-8') as f:
                f.write(str(infoDict)+'\n')
        except:
            traceback.print_exc()
            continue

if __name__=='__main__':
    stock_list_url = 'http://quote.eastmoney.com/stocklist.html'
    stock_info_url = 'https://gupiao.baidu.com/stock/'
    output_file = 'E:\学习相关\廖雪峰\python_study\库\第三章\BaiduStockInfo.txt'
    slist=[]
    getStockList(slist,stock_list_url)
    getStockInfo(slist,stock_info_url,output_file)


结果(超慢的得得得多多多多多多多,还没爬完…不过应该是解析全文默认编码的问题):
2017-09-07 20:08:30 星期四 :earth_asia:github: 爬取结果.txt

淘宝竞价爬虫

首先我们先观察搜索为书包的链接:
第一页:
https://s.taobao.com/search?q=书包&imgfile=&commend=all&ssid=s5-e&search_type=item&sourceId=tb.index&spm=a21bo.50862.201856-taobao-item.1&ie=utf8&initiative_id=tbindexz_20170906
第二页:
https://s.taobao.com/search?q=书包imgfile=&commend=all&ssid=s5-e&search_type=item&sourceId=tb.index&spm=a21bo.50862.201856-taobao-item.1&ie=utf8&initiative_id=tbindexz_20170906&bcoffset=4&ntoffset=4&p4ppushleft=1%2C48&s=44
我们可以观察到书包的属性是q,而每页有44个商品,所以页数的属性是s.
所以我们推测当链接为:
http://s.taobao.com/search?q=书包&s=44
时,时当前搜索目录的第二页.

首先是getHTMLtext:

def getHTMLtext(url):
    try:
        r=requests.get(url)
        r.raise_for_status()
        r.encoding=r.apparent_encoding
        return r.text
    except:
        print("")

然后我们分析代码,比如第一页第一件商品的价钱如下:
第一件
我们在代码页搜索对应的价格89.00,发现对应的标记是’view_price’:
89.00
然后是对应的标题,这里有一些问题,因为第一个东西的标题和显示的对不上,显示的是放在’title’标记中,而不知道什么的标题放在’raw_title’中:

然后我们开始编写parse方法:

def parsePage(til,text):
    try:
        r1=re.compile(r'"view_price":"[\d.]*"')
        r2=re.compile(r'"raw_title":".*?"')
        lip=re.findall(r1,text)
        lit=re.findall(r2,text)
        for i in range(len(lip)):
            price=eval(lip[i].split(':')[1])
            title=eval(lit[i].split(':')[1])
            til.append([price,title])
    except:
        print('')

其中eval可以忽略””这玩意???
最终完成品:

#-*-coding:utf-8-*-
import requests
import re

def getHTMLtext(url):
    try:
        r=requests.get(url)
        r.raise_for_status()
        r.encoding=r.apparent_encoding
        return r.text
    except:
        print("")


def parsePage(til,text):
    try:
        r1=re.compile(r'"view_price":"[\d.]*"')
        r2=re.compile(r'"raw_title":".*?"')
        lip=re.findall(r1,text)
        lit=re.findall(r2,text)
        for i in range(len(lip)):
            price=eval(lip[i].split(':')[1])
            title=eval(lit[i].split(':')[1])
            til.append([price,title])
    except:
        print('')

def printResult(lis):
    tplt="{:4}\t{:8}\t{:16}"
    print(tplt.format('序号','价格','商品名称'))
    for i in range(len(lis)):
        print(tplt.format(i+1,lis[i][0],lis[i][1]))
        if lis[i][0]=='89.00':
            print('===============')

def main():
    goods='书包'
    deepth=3
    infolist=[]
    start_url='https://s.taobao.com/search?q=书包'
    for i in range(deepth):
        try:
            url=start_url+'&s='+str(i*44)
            text=getHTMLtext(url)
            parsePage(infolist,text)
        except:
            continue
    printResult(infolist)

main()

结果:

Python 爬取中国大学排名

首先是爬取的目的地址: :zap:=>2016中国最好大学排名

这里我们使用的是Python的request库和BeautifulSoup库,IDE用的是Anaconda的Spyder,Python version=3.6.

首先我们现在html中搜索清华大学(废话= =).

结果如下:
结果
我们发现结果是在节点为’tbody’中,全部代码中也只有这一个地方有’tbody’.所以我们可以通过查找这个标签,然后再向下查找孩子来找到结果,但是我们知道,他的孩子可能会出现字符串类型,所以我们需要用isinstance(x,bs4.element.Tag),Tag–(标签)来过滤掉其它类型.

于是我们写出A程序:

#CrawUnivRankingA.py
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.cn/zuihaodaxuepaiming2016.html'
    html = getHTMLText(url)
    fillUnivList(uinfo, html)
    printUnivList(uinfo, 20) # 20 univs
main()

打印结果:

可以看出中间的学校缩进不规范,这是因为中文的问题,他是默认按照英文补充空格的.
改进一下,空格用chr(12288)补充:

#CrawUnivRankingB.py
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):
    tplt = "{0:^10}\t{1:{3}^10}\t{2:^10}"
    print(tplt.format("排名","学校名称","总分",chr(12288)))
    for i in range(num):
        u=ulist[i]
        print(tplt.format(u[0],u[1],u[2],chr(12288)))

def main():
    uinfo = []
    url = 'http://www.zuihaodaxue.cn/zuihaodaxuepaiming2016.html'
    html = getHTMLText(url)
    fillUnivList(uinfo, html)
    printUnivList(uinfo, 20) # 20 univs
main()

打印结果:

结束.