這裏的竅門是檢查在進出換頁動作來的請求時您點擊鏈接查看的其他頁面。檢查的方法是使用Chrome的檢測工具(通過按F12)或在Firefox中安裝Firebug擴展。我將在這個答案中使用Chrome的檢測工具。請參閱下面的設置。現在
,我們希望看到的要麼是GET
請求到另一個頁面或POST
請求改變頁面。工具打開時,點擊頁碼。對於一個非常短暫的時刻,只會出現一個請求,並且這是一個POST
方法。所有其他元素將快速跟隨並填充頁面。請參閱下文了解我們正在尋找的內容。
點擊上面POST
方法。它應該彈出一個包含製表符的排序子窗口。點擊Headers
標籤。這個頁面列出了請求標題,幾乎是另一方(例如站點)需要的標識信息,以便您能夠連接(其他人可以比我更好地解釋這個問題)。
只要網址包含頁碼,位置標記或類別等變量,通常情況下,網站就會使用查詢字符串。長話短說,它類似於一個SQL查詢(實際上,它有時是一個SQL查詢),它允許該站點提取所需的信息。如果是這種情況,您可以檢查查詢字符串參數的請求標頭。向下滾動一下,你應該找到它。
正如你所看到的,查詢字符串參數在我們的URL匹配的變量。稍微低一點,你可以看到Form Data
下面有pageNum: 2
。這是關鍵。
POST
請求通常被稱爲表單請求,因爲這些是您在提交表單,登錄到網站等時提出的請求類型。基本上,幾乎任何您必須提交信息的地方。大多數人沒有看到的是POST
請求有一個他們關注的URL。一個很好的例子就是當你登錄到一個網站,並且非常簡單地看到你的地址欄變成某種亂碼網址之後才決定在/index.html
或某些地方。
以上段落的基本含義是,您可以(但不總是)將表單數據追加到您的URL中,並且它將執行POST
請求。要知道您必須追加的確切字符串,請點擊view source
。
測試,如果它的工作原理是將其添加到URL。
的Et瞧,它的工作原理。現在,真正的挑戰是:自動獲取最後一頁,並抓取所有頁面。你的代碼非常多。剩下要做的事情就是獲取頁面的數量,構建一個需要抓取的URL列表,並對它們進行迭代。
修改代碼如下:
from bs4 import BeautifulSoup as bsoup
import requests as rq
import re
base_url = 'http://my.gwu.edu/mod/pws/courses.cfm?campId=1&termId=201501&subjId=ACCY'
r = rq.get(base_url)
soup = bsoup(r.text)
# Use regex to isolate only the links of the page numbers, the one you click on.
page_count_links = soup.find_all("a",href=re.compile(r".*javascript:goToPage.*"))
try: # Make sure there are more than one page, otherwise, set to 1.
num_pages = int(page_count_links[-1].get_text())
except IndexError:
num_pages = 1
# Add 1 because Python range.
url_list = ["{}&pageNum={}".format(base_url, str(page)) for page in range(1, num_pages + 1)]
# Open the text file. Use with to save self from grief.
with open("results.txt","wb") as acct:
for url_ in url_list:
print "Processing {}...".format(url_)
r_new = rq.get(url_)
soup_new = bsoup(r_new.text)
for tr in soup_new.find_all('tr', align='center'):
stack = []
for td in tr.findAll('td'):
stack.append(td.text.replace('\n', '').replace('\t', '').strip())
acct.write(", ".join(stack) + '\n')
我們使用正則表達式來獲得正確的鏈接。然後使用列表理解,我們建立了一個URL字符串列表。最後,我們重複它們。
結果:
Processing http://my.gwu.edu/mod/pws/courses.cfm?campId=1&termId=201501&subjId=ACCY&pageNum=1...
Processing http://my.gwu.edu/mod/pws/courses.cfm?campId=1&termId=201501&subjId=ACCY&pageNum=2...
Processing http://my.gwu.edu/mod/pws/courses.cfm?campId=1&termId=201501&subjId=ACCY&pageNum=3...
[Finished in 6.8s]
希望有所幫助。
編輯:
在百無聊賴中,我想我只是創造了整個類目錄的刮刀。而且,當只有一個可用頁面時,我更新上面和下面的代碼,以便不出錯。
from bs4 import BeautifulSoup as bsoup
import requests as rq
import re
spring_2015 = "http://my.gwu.edu/mod/pws/subjects.cfm?campId=1&termId=201501"
r = rq.get(spring_2015)
soup = bsoup(r.text)
classes_url_list = [c["href"] for c in soup.find_all("a", href=re.compile(r".*courses.cfm\?campId=1&termId=201501&subjId=.*"))]
print classes_url_list
with open("results.txt","wb") as acct:
for class_url in classes_url_list:
base_url = "http://my.gwu.edu/mod/pws/{}".format(class_url)
r = rq.get(base_url)
soup = bsoup(r.text)
# Use regex to isolate only the links of the page numbers, the one you click on.
page_count_links = soup.find_all("a",href=re.compile(r".*javascript:goToPage.*"))
try:
num_pages = int(page_count_links[-1].get_text())
except IndexError:
num_pages = 1
# Add 1 because Python range.
url_list = ["{}&pageNum={}".format(base_url, str(page)) for page in range(1, num_pages + 1)]
# Open the text file. Use with to save self from grief.
for url_ in url_list:
print "Processing {}...".format(url_)
r_new = rq.get(url_)
soup_new = bsoup(r_new.text)
for tr in soup_new.find_all('tr', align='center'):
stack = []
for td in tr.findAll('td'):
stack.append(td.text.replace('\n', '').replace('\t', '').strip())
acct.write(", ".join(stack) + '\n')
這是不是要求或真正poosible任何其他去取HTML東西的工具,如果你想這樣做,你必須去與像硒或webdriver的網絡驅動器,但它的方式更加複雜,要求。 。祝你好運 – brunsgaard 2014-10-21 23:03:30
這真的只是簡單的URL操作。只需使用Google Chrome的檢測工具或Firefox的Firebug檢查「POST」請求即可。請參閱下面的答案。 – Manhattan 2014-10-21 23:05:28
@Nanashi,你也許應該解釋一下如何在你的回答中做你的建議 – 2014-10-21 23:06:51