Selenimum 是什么?
Selenimum浏览器自动化测试框架,测试可以直接运行在浏览器中,通过它请求链接就像是,通过浏览器访问一样,当然功能不止这些,回头在慢慢看。
为什么要用Selenimum
如果是静态网站,通常只需要请求url 获取html 文本就可以解析了碰到异步加载的需要通过Chrome调试工具或者抓包工具获取所有请求,找出我们需要的url,如果顺利的话通常就是一个URL请求直接返回json或html 内容,但是复杂的请求就很头痛了,比如返回的是一段html 中掺杂了js脚本,Unicode 编码后的一堆符号,一大堆的<div>嵌套, 或者是调用混淆后的js中某个方法对参数加密等等,这个时候就很适合用selenimum,不管什么花里胡哨的请求,交给浏览器解析,直到获取到了纯洁的html 在去爬取内容。
下载依赖
https://sites.google.com/a/chromium.org/chromedriver/downloads 去官网下载ChromeDrive,需要科学上网。
用Selenimum 爬取网站内容
这里我爬取的是纳斯达克上市公司市值为前150的公司列表,网址:https://www.nasdaq.com/screening/companies-by-industry.aspx?sortname=marketcap&sorttype=1&exchange=NASDAQ&pagesize=150 打开后能看到图1 所示的表格:
图1在Chrome浏览器中右键点击检查就可以定位到表格的html 标签, id是CompanylistResults:
图2可以看到tbody 标签下就是表格的行, 这里点开tr标签就可以看到数据:
图3这里可以看到有公司的名称, 市值, 股票代码, 国家,IPO年份,行业,这些就是我想爬取的内容, 程序上我要做的就是:
1.打开URL 等待表格加载完成(异步加载表格)
2.找到表格的节点,遍历所有的行,解析每行的数据
过程很简单,直接上测试代码:
class TestMethod(unittest.TestCase):
def setUp(self):
#初始化driver
self.driver = webdriver.Chrome("/Users/younchen/bin/chromedriver")
def tearDown(self):
#关闭driver
self.driver.close()
def test(self):
global element
try:
#url = https://www.nasdaq.com/screening/companies-by-industry.aspx?sortname=marketcap&sorttype=1&exchange=NASDAQ&pagesize=150
self.driver.get(url)
#设置超时为10秒, 尝试在10秒内找到id对应的元素
element = WebDriverWait(self.driver, 10).until(
EC.presence_of_element_located((By.ID, 'CompanylistResults')))
comp_list = []
if isinstance(element, WebElement):
#查找表格中所有的行
tb_rows = element.find_elements_by_xpath('//tr')
for tb_row in tb_rows:
tds = tb_row.find_elements_by_xpath('.//td')
#解析数据
comp_list.append(process_tbs(tds))
for table in comp_list:
table.print_info()
except TimeoutException:
pass
element 对应的类是WebElement 是一个节点id为CompanylistResult 的Dom对象,在这遍历和解析子节点使用的是xpath (一种xml解析语法代替正则表达式) , ‘//tr’ 这句语中表示在当前节点中寻找所有的tr标签,接下来要遍历<tr>也就是表格的每一行,process_tbs方法:
def process_com_info(tds):
comp_name = tds[0].text
comp_code = tds[1].text
price = tds[2].text
country = tds[4].text
industry = tds[6].text
co = Company(comp_name, price, comp_code, country, industry)
co.print_info()
def process_tbs(tds):
if len(tds) > 3:
process_com_info(tds)
class Company(object):
def __init__(self, name=None, price=None, code=None, country=None, industry=None):
self.name = name
self.price = price
self.code = code
self.country = country
self.industry = industry
def print_info(self):
print("name: %s code: %s market value:%s country:%s industry:%s" % (self.name, self.code,
self.price, self.country, self.industry))
因为表格中每个需要解析的行之间都会有不需要解析的行见图1, 所以元素少于3个行视为无效行,过滤即可, 根据图三,解析<tr>中的<td>标签对应的数据,并将数据抽象出来用类company来表示, 运行结果如下:
图4
参考:
http://www.runoob.com/xpath/xpath-tutorial.html
https://selenium-python.readthedocs.io/
网友评论