【Python爬虫9】Python网络爬虫实例实战

简介: 爬Google搜索引擎爬Facebook和Linkein1自动化登录Facebook2提取Facebook的API数据3自动化登录Linkedin爬在线商店Gap爬宝马官网爬取Google真实的搜索表单爬取依赖JavaScript的网站Facebook爬取典型在线商店Gap爬取拥有地图接口的宝马官网1.

  • 爬取Google真实的搜索表单
  • 爬取依赖JavaScript的网站Facebook
  • 爬取典型在线商店Gap
  • 爬取拥有地图接口的宝马官网

1.爬Google搜索引擎

# -*- coding: utf-8 -*-

import sys
import urllib
import urlparse
import lxml.html
from downloader import Downloader

def search(keyword):
    D = Downloader()
    url = 'https://www.google.com/search?q=' + urllib.quote_plus(keyword)
    html = D(url)
    tree = lxml.html.fromstring(html)
    links = []
    for result in tree.cssselect('h3.r a'):
        link = result.get('href')
        qs = urlparse.urlparse(link).query
        links.extend(urlparse.parse_qs(qs).get('q', []))
    return links

if __name__ == '__main__':
    try:
        keyword = sys.argv[1]
    except IndexError:
        keyword = 'test'
    print search(keyword)

注意:提取Google搜索结果时注意爬取延时问题,否则下载速度过快会出现验证码处理。

2.爬Facebook和Linkein

查看Packt出版本的Facebook页面源代码时,可以找到最开始的几篇日志,但后面的日志只有浏览器滚动时才会通过AJAX加载。
- 电脑网页端:http://www.facebook.com/PacktPub
- 移动网页端:http://m.facebook.com/PacktPub

2.1自动化登录Facebook

这些AJAX的数据无法简化提取,虽然这些AJAX事件可以被卧逆向工程,但是不同类型的Facebook页面使用了不用的AJAX调用。所以下面用Selenium渲染实现自动化登录Facebook。

# -*- coding: utf-8 -*-

import sys
from selenium import webdriver

def facebook(username, password, url):
    driver = webdriver.Firefox()
    driver.get('https://www.facebook.com')
    driver.find_element_by_id('email').send_keys(username)
    driver.find_element_by_id('pass').send_keys(password)
    driver.find_element_by_id('login_form').submit()
    driver.implicitly_wait(30)
    # wait until the search box is available,
    # which means have succrssfully logged in
    search = driver.find_element_by_id('q')
    # now are logged in so can navigate to the page of interest
    driver.get(url)
    # add code to scrape data of interest here
    #driver.close()

if __name__ == '__main__':
    try:
        username = sys.argv[1]
        password = sys.argv[2]
        url = sys.argv[3]
    except IndexError:
        print 'Usage: %s <username> <password> <url>' % sys.argv[0]
    else:
        facebook(username, password, url)

2.2提取Facebook的API数据

Facebook提供了一些API数据,如果允许访问这些数据,下面就提取Packt出版社页面的数据。

# -*- coding: utf-8 -*-

import sys
import json
import pprint
from downloader import Downloader

def graph(page_id):
    D = Downloader()
    html = D('http://graph.facebook.com/' + page_id)
    return json.loads(html)

if __name__ == '__main__':
    try:
        page_id = sys.argv[1]
    except IndexError:
        page_id = 'PacktPub'
    pprint.pprint(graph(page_id))

Facebook开发者文档:https://developers.facebook.com/docs/graph-api 这些API调用多数是设计给已授权的facebook用户交互的facebook应用的,要想提取比如用户日志等更加详细的信息,仍然需要爬虫。

2.3自动化登录Linkedin

# -*- coding: utf-8 -*-

import sys
from selenium import webdriver

def search(username, password, keyword):
    driver = webdriver.Firefox()
    driver.get('https://www.linkedin.com/')
    driver.find_element_by_id('session_key-login').send_keys(username)
    driver.find_element_by_id('session_password-login').send_keys(password)
    driver.find_element_by_id('signin').click()
    driver.implicitly_wait(30)
    driver.find_element_by_id('main-search-box').send_keys(keyword)
    driver.find_element_by_class_name('search-button').click()
    driver.find_element_by_css_selector('ol#results li a').click()
    # Add code to scrape data of interest from LinkedIn page here
    #driver.close()

if __name__ == '__main__':
    try:
        username = sys.argv[1]
        password = sys.argv[2]
        keyword = sys.argv[3]
    except IndexError:
        print 'Usage: %s <username> <password> <keyword>' % sys.argv[0]
    else:
        search(username, password, keyword)

3.爬在线商店Gap

Gap拥有一个结构化良好的网站,通过Sitemap可以帮助网络爬虫定位到最新的内容。从http://www.gap.com/robots.txt 中可以发现网站地图Sitemap: http://www.gap.com/products/sitemap_index.html

This XML file does not appear to have any style information associated with it. The document tree is shown below.
<sitemapindex xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
<sitemap>
<loc>http://www.gap.com/products/sitemap_1.xml</loc>
<lastmod>2017-01-30</lastmod>
</sitemap>
<sitemap>
<loc>http://www.gap.com/products/sitemap_2.xml</loc>
<lastmod>2017-01-30</lastmod>
</sitemap>
</sitemapindex>

如上网站地图册链接的内容仅仅是索引,其索引的网站地图才是数千种产品类目的链接,比如:http://www.gap.com/products/blue-long-sleeve-shirts-for-men.jsp 。由于这里有大量要爬取的内容,因此我们将使用第4篇开发的多线和爬虫,并支持一人可选的回调参数。

# -*- coding: utf-8 -*-

from lxml import etree
from threaded_crawler import threaded_crawler

def scrape_callback(url, html):
    if url.endswith('.xml'):
        # Parse the sitemap XML file
        tree = etree.fromstring(html)
        links = [e[0].text for e in tree]
        return links
    else:
        # Add scraping code here
        pass       

def main():
    sitemap = 'http://www.gap.com/products/sitemap_index.xml'
    threaded_crawler(sitemap, scrape_callback=scrape_callback)

if __name__ == '__main__':
    main() 

该回调函数首先下载到的URL扩展名。如果扩展名是.xml,则用lxml的etree模块解析XML文件并从中提取链接。否则,认为这是一个类目URL(这例没有实现提取类目的功能)。

4.爬宝马官网

宝马官方网站中有一个查询本地经销商的搜索工具,其网址为https://www.bmw.de/de/home.html?entryType=dlo
该工具将地理位置作为输入参数,然后在地图上显示附近的经销商地点,比如输入BerlinLook For
我们使用开发者工具会发现搜索触发了AJAX请求:
https://c2b-services.bmw.com/c2b-localsearch/services/api/v3/clients/BMWDIGITAL_DLO/DE/pois?country=DE&category=BM&maxResults=99&language=en&lat=52.507537768880056&lng=13.425269635701511
maxResults默认设为99,我们可以增大该值。AJAX请求提供了JSONP格式的数据,其中JSONP是指填充模式的JSON(JSON with padding)。这里的填充通常是指要调用的函数,而函数的参数则为纯JSON数据。本例调用的是callback函数,要想使用Pythonr的json模块解析该数据,首先需要将填充的部分截取掉。

# -*- coding: utf-8 -*-

import json
import csv
from downloader import Downloader

def main():
    D = Downloader()
    url = 'https://c2b-services.bmw.com/c2b-localsearch/services/api/v3/clients/BMWDIGITAL_DLO/DE/pois?country=DE&category=BM&maxResults=%d&language=en&lat=52.507537768880056&lng=13.425269635701511'
    jsonp = D(url % 1000) ###callback({"status:{...}"})
    pure_json = jsonp[jsonp.index('(') + 1 : jsonp.rindex(')')]
    dealers = json.loads(pure_json) ###
    with open('bmw.csv', 'w') as fp:
        writer = csv.writer(fp)
        writer.writerow(['Name', 'Latitude', 'Longitude'])
        for dealer in dealers['data']['pois']:
            name = dealer['name'].encode('utf-8')
            lat, lng = dealer['lat'], dealer['lng']
            writer.writerow([name, lat, lng])

if __name__ == '__main__':
    main() 
>>> dealers.keys() #[u'status',u'count',u'data',...]
>>> dealers['count'] #显示个数
>>> dealers['data']['pois'][0] #第一个经销商数据

Wu_Being 博客声明:本人博客欢迎转载,请标明博客原文和原链接!谢谢!
【Python爬虫系列】《【Python爬虫9】Python网络爬虫实例实战》http://blog.csdn.net/u014134180/article/details/55508272
Python爬虫系列的GitHub代码文件https://github.com/1040003585/WebScrapingWithPython

Wu_Being 吴兵博客接受赞助费二维码

如果你看完这篇博文,觉得对你有帮助,并且愿意付赞助费,那么我会更有动力写下去。

目录
相关文章
|
1天前
|
SQL 安全 数据库
Python Web开发者必学:SQL注入、XSS、CSRF攻击与防御实战演练!
【7月更文挑战第26天】在 Python Web 开发中, 安全性至关重要。本文聚焦 SQL 注入、XSS 和 CSRF 这三大安全威胁,提供实战防御策略。SQL 注入可通过参数化查询和 ORM 框架来防范;XSS 则需 HTML 转义用户输入与实施 CSP;CSRF 防御依赖 CSRF 令牌和双重提交 Cookie。掌握这些技巧,能有效加固 Web 应用的安全防线。安全是持续的过程,需贯穿开发始终。
6 1
Python Web开发者必学:SQL注入、XSS、CSRF攻击与防御实战演练!
|
4天前
|
前端开发 API 数据库
告别繁琐,拥抱简洁!Python RESTful API 设计实战,让 API 调用如丝般顺滑!
【7月更文挑战第23天】在Python的Flask框架下构建RESTful API,为在线商店管理商品、订单及用户信息。以商品管理为例,设计简洁API端点,如GET `/products`获取商品列表,POST `/products`添加商品,PUT和DELETE则分别用于更新和删除商品。使用SQLAlchemy ORM与SQLite数据库交互,确保数据一致性。实战中还应加入数据验证、错误处理和权限控制,使API既高效又安全,便于前端或其他服务无缝对接。
27 9
|
3天前
|
算法 搜索推荐 开发者
别再让复杂度拖你后腿!Python 算法设计与分析实战,教你如何精准评估与优化!
【7月更文挑战第23天】在Python编程中,掌握算法复杂度—时间与空间消耗,是提升程序效能的关键。算法如冒泡排序($O(n^2)$时间/$O(1)$空间),或使用Python内置函数找最大值($O(n)$时间),需精确诊断与优化。数据结构如哈希表可将查找从$O(n)$降至$O(1)$。运用`timeit`模块评估性能,深入理解数据结构和算法,使Python代码更高效。持续实践与学习,精通复杂度管理。
22 9
|
2天前
|
网络协议 开发者 Python
网络编程小白秒变大咖!Python Socket基础与进阶教程,轻松上手无压力!
【7月更文挑战第25天】在网络技术快速发展的背景下, Python因其简洁的语法和强大的库支持成为学习网络编程的理想选择。
18 5
|
4天前
|
数据采集 Web App开发 存储
Python-数据爬取(爬虫)
【7月更文挑战第24天】
31 7
|
2天前
|
网络协议 开发者 Python
深度探索Python Socket编程:从理论到实践,进阶篇带你领略网络编程的魅力!
【7月更文挑战第25天】在网络编程中, Python Socket编程因灵活性强而广受青睐。本文采用问答形式深入探讨其进阶技巧。**问题一**: Socket编程基于TCP/IP,通过创建Socket对象实现通信,支持客户端和服务器间的数据交换。**问题二**: 提升并发处理能力的方法包括多线程(适用于I/O密集型任务)、多进程(绕过GIL限制)和异步IO(asyncio)。**问题三**: 提供了一个使用asyncio库实现的异步Socket服务器示例,展示如何接收及响应客户端消息。通过这些内容,希望能激发读者对网络编程的兴趣并引导进一步探索。
11 4
|
1天前
|
网络协议 Python
网络世界的建筑师:Python Socket编程基础与进阶,构建你的网络帝国!
【7月更文挑战第26天】在网络的数字宇宙中,Python Socket编程是开启网络世界大门的钥匙。本指南将引领你从基础到实战,成为网络世界的建筑师。
6 2
|
2天前
|
开发者 Python
Python Socket编程:不只是基础,更有进阶秘籍,让你的网络应用飞起来!
【7月更文挑战第25天】在网络应用蓬勃发展的数字时代,Python凭借其简洁的语法和强大的库支持成为开发高效应用的首选。本文通过实时聊天室案例,介绍了Python Socket编程的基础与进阶技巧,包括服务器与客户端的建立、数据交换等基础篇内容,以及使用多线程和异步IO提升性能的进阶篇。基础示例展示了服务器端监听连接请求、接收转发消息,客户端连接服务器并收发消息的过程。进阶部分讨论了如何利用Python的`threading`模块和`asyncio`库来处理多客户端连接,提高应用的并发处理能力和响应速度。掌握这些技能,能使开发者在网络编程领域更加游刃有余,构建出高性能的应用程序。
10 3
|
2天前
|
机器学习/深度学习 数据可视化 数据挖掘
从菜鸟到高手,一图胜千言!Python数据分析与机器学习中的数据可视化实战秘籍!
【7月更文挑战第24天】在数据科学中,数据可视化是探索与沟通的关键。从Matplotlib的基础绘图到Seaborn的统计图形,再到Plotly的交互式图表,这些工具助你成为数据叙事大师。示例代码涵盖正弦波图、小费散点图及鸢尾花分布图,展现从简单到复杂的可视化之旅。掌握这些技巧,你就能更有效地解析和呈现数据故事。