我正在运行此课程网站的抓取工具,我想知道一旦将它放入beautifulsoup,是否有更快的方法来抓取该页面。它花费的时间比我预期的要长。
提示?
from selenium import webdriver
from selenium.webdriver.common.keys import Keys
from selenium.webdriver.support.ui import Select
from selenium.webdriver.support import expected_conditions as EC
from bs4 import BeautifulSoup
driver = webdriver.PhantomJS()
driver.implicitly_wait(10) # seconds
driver.get("https://acadinfo.wustl.edu/Courselistings/Semester/Search.aspx")
select = Select(driver.find_element_by_name("ctl00$Body$ddlSchool"))
parsedClasses = {}
for i in range(len(select.options)):
print i
select = Select(driver.find_element_by_name("ctl00$Body$ddlSchool"))
select.options[i].click()
upperLevelClassButton = driver.find_element_by_id("Body_Level500")
upperLevelClassButton.click()
driver.find_element_by_name("ctl00$Body$ctl15").click()
soup = BeautifulSoup(driver.page_source, "lxml")
courses = soup.select(".CrsOpen")
for course in courses:
courseName = course.find_next(class_="ResultTable")["id"][13:]
parsedClasses[courseName] = []
print courseName
for section in course.select(".SecOpen"):
classInfo = section.find_all_next(class_="ItemRowCenter")
parsedClasses[courseName].append((int(classInfo[0].string), int(classInfo[1].string), int(classInfo[2].string)))
print parsedClasses
print parsedClasses['FL2014' + 'A46' + '3284']
driver.quit()
好的,您可以通过以下方法真正加快速度:
BeautifulSoup
使用lxml
解析器SoupStrainer
解析页面的唯一相关部件由于这是ASP.NET
生成的形式,并且由于它的安全性功能,事情变得更加复杂。这是完整的代码,请不要害怕-我添加了注释并提出了疑问:
import re
from bs4 import BeautifulSoup, SoupStrainer
import requests
# start session and get the search page
session = requests.Session()
response = session.get('https://acadinfo.wustl.edu/Courselistings/Semester/Search.aspx')
# parse the search page using SoupStrainer and lxml
strainer = SoupStrainer('form', attrs={'id': 'form1'})
soup = BeautifulSoup(response.content, 'lxml', parse_only=strainer)
# get the view state, event target and validation values
viewstate = soup.find('input', id='__VIEWSTATE').get('value')
eventvalidation = soup.find('input', id='__EVENTVALIDATION').get('value')
search_button = soup.find('input', value='Search')
event_target = re.search(r"__doPostBack\('(.*?)'", search_button.get('onclick')).group(1)
# configure post request parameters
data = {
'__EVENTTARGET': event_target,
'__EVENTARGUMENT': '',
'__LASTFOCUS': '',
'__VIEWSTATE': viewstate,
'__EVENTVALIDATION': eventvalidation,
'ctl00$Body$ddlSemester': '201405',
'ctl00$Body$ddlSession': '',
'ctl00$Body$ddlDept': '%',
'ctl00$Body$ddlAttributes': '0',
'ctl00$Body$Days': 'rbAnyDay',
'ctl00$Body$Time': 'rbAnyTime',
'ctl00$Body$cbMorning': 'on',
'ctl00$Body$cbAfternoon': 'on',
'ctl00$Body$cbEvening': 'on',
'ctl00$Body$tbStart': '9:00am',
'ctl00$Body$tbEnds': '5:00pm',
'ctl00$Body$ddlUnits': '0',
'ctl00$Body$cbHideIStudy': 'on',
'ctl00$Body$courseList$hidHoverShow': 'Y',
'ctl00$Body$courseList$hidDeptBarCnt': '',
'ctl00$Body$courseList$hidSiteURL': 'https://acadinfo.wustl.edu/Courselistings',
'ctl00$Body$courseList$hidExpandDetail': '',
'ctl00$Body$hidDay': ',1,2,3,4,5,6,7',
'ctl00$Body$hidLevel': '1234',
'ctl00$Body$hidDefLevel': ''
}
# get the list of options
strainer = SoupStrainer('div', attrs={'id': 'Body_courseList_tabSelect'})
options = soup.select('#Body_ddlSchool > option')
for option in options:
print "Processing {option} ...".format(option=option.text)
data['ctl00$Body$ddlSchool'] = option.get('value')
# make the search post request for a particular option
response = session.post('https://acadinfo.wustl.edu/Courselistings/Semester/Search.aspx',
data=data)
result_soup = BeautifulSoup(response.content, parse_only=strainer)
print [item.text[:20].replace(' ', ' ') + '...' for item in result_soup.select('div.CrsOpen')]
印刷品:
Processing Architecture ...
[u'A46 ARCH 100...', u'A46 ARCH 111...', u'A46 ARCH 209...', u'A46 ARCH 211...', u'A46 ARCH 266...', u'A46 ARCH 305...', u'A46 ARCH 311...', u'A46 ARCH 323...', u'A46 ARCH 328...', u'A46 ARCH 336...', u'A46 ARCH 343...', u'A46 ARCH 350...', u'A46 ARCH 355...', u'A46 ARCH 411...', u'A46 ARCH 422...', u'A46 ARCH 428...', u'A46 ARCH 436...', u'A46 ARCH 445...', u'A46 ARCH 447...', u'A46 ARCH 465...', u'A48 LAND 451...', u'A48 LAND 453...', u'A48 LAND 461...']
Processing Art ...
[u'F10 ART 1052...', u'F10 ART 1073...', u'F10 ART 213A...', u'F10 ART 215A...', u'F10 ART 217B...', u'F10 ART 221A...', u'F10 ART 231I...', u'F10 ART 241D...', u'F10 ART 283T...', u'F10 ART 301A...', u'F10 ART 311E...', u'F10 ART 313D...', u'F10 ART 315B...', u'F10 ART 317H...', u'F10 ART 323A...', u'F10 ART 323B...', u'F10 ART 323C...', u'F10 ART 329C...', u'F10 ART 337E...', u'F10 ART 337F...', u'F10 ART 337H...', u'F10 ART 385A...', u'F10 ART 391M...', u'F10 ART 401A...', u'F10 ART 411E...', u'F10 ART 413D...', u'F10 ART 415B...', u'F10 ART 417H...', u'F10 ART 423A...', u'F10 ART 423B...', u'F10 ART 423C...', u'F10 ART 429C...', u'F10 ART 433C...', u'F10 ART 433D...', u'F10 ART 433E...', u'F10 ART 433K...', u'F10 ART 461C...', u'F10 ART 485A...', u'F20 ART 111P...', u'F20 ART 115P...', u'F20 ART 1186...', u'F20 ART 119C...', u'F20 ART 127A...', u'F20 ART 133B...', u'F20 ART 135G...', u'F20 ART 135I...', u'F20 ART 135J...', u'F20 ART 1361...', u'F20 ART 1363...', u'F20 ART 1713...', u'F20 ART 219C...', u'F20 ART 2363...', u'F20 ART 2661...', u'F20 ART 281S...', u'F20 ART 311P...', u'F20 ART 315P...', u'F20 ART 3183...', u'F20 ART 333B...', u'F20 ART 335A...', u'F20 ART 335J...', u'F20 ART 3713...', u'F20 ART 381S...', u'F20 ART 415P...', u'F20 ART 435I...']
...
当然,这里还有一些需要改进的地方,例如,我已经对其他表单值进行了硬编码-您可能应该解析可能的值并适当地设置它们。
另一个改进是将其与grequests
:
GRequests允许您将Requests与Gevent一起使用,以轻松进行异步HTTP Requests。
如您所见,当您处于较高级别并通过WebDriver与浏览器进行交互时,您不必担心实际要向服务器发送请求以获取数据的请求。这使自动化很容易,但是会很慢。当您使用低级自动化时,您有更多选择来加快处理速度,但是实现的复杂性却增长很快。另外,请考虑这种解决方案的可靠性如何。那么可能会坚持使用“黑匣子”解决方案并坚持下去selenium
吗?
我也尝试使用以下方法解决问题:
mechanize
robobrowser
mechanicalsoup
但由于不同的原因而失败(可以为您提供相关的错误消息)。但是,所有这三个工具都应该有助于简化解决方案。
另请参阅类似的线程:
问题内容: 我正在运行一个Python程序,该程序可获取UTF-8编码的网页,并使用BeautifulSoup从HTML中提取一些文本。 但是,当我将此文本写入文件(或在控制台上打印)时,它会以意外的编码方式写入。 示例程序: 运行此结果: 但是我希望Python Unicode字符串在单词中呈现为: 我已经试过了“fromEncoding”参数传递给BeautifulSoup,并试图与该对象,但
问题内容: 我试图在网页上的特定“输入”标签中提取单个“值”属性的内容。我使用以下代码: 我收到TypeError:列表索引必须是整数,而不是str 即使从Beautifulsoup文档中我了解到字符串在这里也不应该是一个问题…但是我没有专家,我可能会误解了。 问题答案: 返回所有找到的元素的列表,因此: 是一个列表(可能仅包含一个元素)。根据你的确切要求,你应该执行以下操作: 或使用仅返回一个(
问题内容: 基本上,我想使用来严格抓取网页上的可见文本。例如,此网页是我的测试用例。我主要想获取正文文本(文章),甚至在这里和那里甚至几个标签名称。我已经尝试过在这个SO问题中返回不想要的标签和html注释的建议。我无法弄清楚该函数所需的参数,以便仅获取网页上的可见文本。 那么,我应该如何查找除脚本,注释,CSS等之外的所有可见文本? 问题答案: 尝试这个:
问题内容: 我没有使用python,BeautifulSoup,Selenium等的经验,但是我很想从网站上抓取数据并将其存储为csv文件。我需要的单个数据样本编码如下(一行数据)。 我需要的输出是 我发现这些数据没有ID或类,但仍以通用文本形式出现在网站中。为此,我分别尝试使用BeautifulSoup和Python Selenium,在这两种方法中,我都陷入了无法提取的麻烦,因为我没有看到任何
问题内容: 我正在尝试从报纸(纽约时间)收集日期,标题和内容。 我有日期和标题,但没有完整的文章。下面是我用来抓取日期和标题的代码。 除了日期,标题外,我还想抓全文。 问题答案: 有可能的。您必须获取该文章的每个链接并将其拉出。我在下面添加了它,还整理了一下文章,因为有多余的空格,当您将它们全部合并在一起时,文本中没有空格。 输出:
问题内容: 如何检索网页链接并使用Python复制链接的URL地址? 问题答案: 这是在中使用类的一小段代码:
问题内容: 我正在尝试解析一个网站,并通过BeautifulSoup.findAll获取一些信息,但它并没有全部找到。.我正在使用python3 代码是这个 它只打印一半… 问题答案: 不同的HTML解析器对损坏的HTML的处理方式不同。该页面提供了损坏的HTML,解析器对此的处理不佳: 标准库在此特定页面上的麻烦较少: 使用将其转换为您的特定代码示例,您将这样指定解析器:
问题内容: 是否可以使用BeautifulSoup从HTML中删除脚本标签及其所有内容,还是必须使用正则表达式或其他内容? 问题答案: