顯示具有 BeautifulSoup 標籤的文章。 顯示所有文章
顯示具有 BeautifulSoup 標籤的文章。 顯示所有文章

2017年6月12日 星期一

Python邊學邊記錄-Crawler網路爬蟲-實戰-虎航

Python Crawler

在爬虎航的航班資訊的時候,好像不是這麼標準SOP就可以取得網頁資料了!

透過開發者工具可以發現,這個SelectFlights.aspx是有來源網址的,這代表是在一個地方先搜尋之後再到這來。
Python Crawler

再看一下Search.aspx的部份

Python Crawler

Python Crawler

另外也可以看一下Search.aspx的response會發現是空的!
這代表在這邊是沒有回傳資料的,而SelectFlights.aspx的response是有的!
Python Crawler

Python Crawler

所以,程式的部份就需要改透過request.session來處理!
resp = requests.session()

resp1 = resp.post('https://booking.tigerairtw.com/Search.aspx', data=form_data)
resp2 = resp.get('https://booking.tigerairtw.com/SelectFlights.aspx')

soup = BeautifulSoup(resp2, 'html5lib')

這樣子,就可以取得航班資訊了!
測試的時候更新太多次,被ban了...技術不好就是一下子會被發現是爬蟲…改用selenium了!

2017年5月25日 星期四

Python邊學邊記錄-Crawler網路爬蟲-第四課-爬表格

Python Crawler

今天的課是學怎麼去爬表格的資料,作法上跟之前在寫ASP.NET的時候處理GridView差不多,果然是萬變不離其宗!

假如網頁畫面如下:
項次 項目 價格 連結
1 國文 1200 http://123.com
2 英文 1800 http://123.com
3 數學 1500 http://123.com
4 理化 2000 http://123.com

首先,一樣要先透過requests.get連到該目標網址,然後一樣丟給了BeauitfulSoup去處理!

resp = requests.get('目標網址')
soup = BeautifulSoup(resp.text, 'html.parser')

tr就跟row一樣,所以先取tr資料
rows = soup.find('table', 'table').tbody.find_all('tr')

然後就透過迴圈去把所有tr的價格資料取出,價格td在第三欄,以index來計算的話是2。
(註:目前只有遇到generol的index是從1開始@@)

for row in rows:
  price = row.find_all('td')[2].text  

基本上,這樣子就可以取得price了。

如果有想要換平均課程價格的話,那就可以先宣告一個list
prices = []

然後在迴圈中append進去
for row in rows:
  price = row.find_all('td')[2].text
  prices.append(int(price))

總金額
sum(prices)
len(prices)
課程數

python的list加總真的很方便!

另一種作法的話,就是透過tag的父子兄關係去做定位。
table
  tr
    td
    td
    td價格
    td連結
       a

我們可以從『a』這個tag去找他爸『td連結』再找他兄弟『td價格』
這時候的作法就變成先取得『a』的定位
links = soup.find_all('a')
接著透過『a』來找他的父兄
for link in links:
  price=link.parent.previous_sibling.text

.parent(父).previous_sibling(兄) 作法上跟處理一些網頁是一樣的。

如果要把所有的表格資料列印出來的話,作法是一樣的。
rows = soup.find('table','table').find_all('tr') # 先取得所有的tr資料
for row in rows:
  #另一種取得所有td的方式 
  #all_tds = [td for td in row.children]
  all_tds = row.find_all('td') # 取得所有的td
  print(all_tds[0].text..XXXX) # 透過index去取值即可

當然了,如果有時候連結沒有放上去的話,那就會造成異常,所以需要防呆!
rows = soup.find('table','table').find_all('tr') # 先取得所有的tr資料
for row in rows:
  all_tds = row.find_all('td') # 取得所有的td
  if 'href' in all_tds[3].a.attrs: # 確認href是否存在
    href = all_tds[3].a['href']
  else:
    href = None
  print(all_tds[0].text..XXXX) # 透過index去取值即可

另一種作法的話就是可以透過stripped_strings來處理!
rows = soup.find('table','table').find_all('tr') # 先取得所有的tr資料
for row in rows:
  print([s for s in row.stripped_strings])

s for s in subsets 就等於
ss = []
for s in subsets(s):
  ss.apped(s)

2017年5月24日 星期三

Python邊學邊記錄-Crawler網路爬蟲-第三課-BeautifulSoup

BeautifulSoup

BeautifulSoup是一套在爬取網頁資訊上非常好用的lib,當然python上還有另一套selenium也可以做的到。

resp = requests.get('目標網址')
soup = BeautifulSoup(resp.text, 'html.parser')

取得第一個tag

soup.find('tagname')
或是
soup.tagname
這兩個方式都是可以取得第一個tag的方式。

取得tag底下的child tag

print(soup.tag.child tag.text)
print(soup.div.a.text)
意即取第一個div底下的a的文字

取得所有的tag

main_titles = soup.find_all('h4')
for title in main_titles:
    print(title.a.text)

透過find_all的方式可以取得所有需求的tag,再透過迴圈的方式將逐一處理
作法上還可以另外如下加上class的條件

soup.find_all('h4', 'card-title')
soup.find_all('h4', {'class': 'card-title'})
soup.find_all('h4', class_='card-title')
上面的意思就是取tag為h4且class為card-title的資料

透過id取得元件

soup.find(id='mac-p')

如果自訂了標籤『data-index』,並且想透用該tag來做條件的話,因為包含了『-』,會導致異常,所以只能透過最標準的作法來處理。
soup.find('', {'data-index': '123'})
tag的部份不給值,直接定義要搜尋的條件。

取得網頁上所有文字

divs = soup.find_all('div', 'content')
for div in divs:
    1-使用 text (會包含許多換行符號跟空格)    print(div.text)    2-使用 tag 定位     print(div.h6.text.strip(), div.h4.a.text.strip(), div.p.text.strip())    3-使用 .stripped_strings    print([s for s in div.stripped_strings])


2017年5月23日 星期二

Python邊學邊記錄-Crawler網路爬蟲-第一課-開始爬

Python Crawler需求套件:


  • BeautifulSoup
  • Requests
首先,要先import requests跟BeautifulSoup

Requests是一個在網路資源取得的套件,可以get、post、delete!
我們要從網站取得資料的時候可以透過requests.get('網址')來操作執行!

resp = requests.get('http://martychen920.blogspot.com/p/python.html')

python Requests

這時候,resp取得資料之後,其實有很多的操作方法,像status確認網頁狀態,這邊我們要將網頁資料整個拉出的話,就是text!
所以,可以用print(resp.text)去看,會發現整個html都被搬過來了。

python Requests

接著,這html的資料還要再過手,轉成BeautifulSoup看的懂的格式!

soup = BeautifulSoup(resp.text,'html.parser')

這樣,就可以把資料轉成BeautifulSoup這套件自己可以懂的格式了。
這時候去print(soup),也會是一堆像極了html的資料。
接著就可以去操作這soup上的資料了!

soup.find('h1').text

這樣就可以去找尋『h1』並取得文字資料。
假設是『藤原栗子工作室

如果直接去print(soup.find('h1'))的話也是可以執行的,只是會連tag都帶出來而以。
就會是『<h1>藤原栗子工作室</h1>