scrapy分页抓取网页( Scrapy爬虫框架和如何新建Python虚拟环境师列表和信息?)

优采云 发布时间: 2021-10-08 19:04

  scrapy分页抓取网页(

Scrapy爬虫框架和如何新建Python虚拟环境师列表和信息?)

  

  目标和步骤

  爬虫目标:从简单心理学网站获取心理咨询师名单和信息。

  学习目标:

  简单心理学网站有两种专家,“会诊”和“心理咨询师”。这里我们尝试先抓取顾问的信息。

  顾问展示列表比较简单,总共有49页,每页有10个或11个顾问(有点棘手……)。只需抓取每个页面上的信息。

  步骤分解:

  新项目和爬虫

  上一篇文章介绍了Scrapy爬虫框架以及如何新建Python虚拟环境。现在让我们创建一个新的 Scrapy 爬虫项目:

  1

  scrapy startproject jdxl

  Scrapy 生成了以下文件

  1

2

3

4

5

6

7

8

9

  ├── jdxl

│   ├── __init__.py

│   ├── items.py

│   ├── middlewares.py

│   ├── pipelines.py

│   ├── settings.py

│   └── spiders

│   └── __init__.py

└── scrapy.cfg

  我们在蜘蛛文件夹中创建了一个新的爬虫文件顾问.py。

  然后在items.py中定义要爬取的item:

  1

2

3

4

5

6

7

8

9

  class JdxlItem(scrapy.Item):

# define the fields for your item here like:

# name = scrapy.Field()

name = scrapy.Field() #姓名

url = scrapy.Field() #链接

info = scrapy.Field() #简介

zx_type = scrapy.Field() #咨询类型

location = scrapy.Field() #地点

price = scrapy.Field() #价格

  抓取页面信息

  打开爬虫顾问.py,开始编写爬虫程序。

  不要忘记先导入上面定义的对象:

  1

  from jdxl.items import JdxlItem

  问题一:如何设置起始网址?

  打开心理咨询师列表页面,然后翻到第二页,发现网址是一个很长的字符串:

  1

  https://www.jiandanxinli.com/experts?filter%5Bcity_id%5D=&filter%5Bfield_id%5D=&filter%5Bgender%5D=&filter%5Bonly_available%5D=&filter%5Bonly_junior%5D=&filter%5Bonly_online%5D=&filter%5Bprice%5D=&filter%5Bq%5D=&filter%5Bsect_id%5D=&filter%5Btarget_id%5D=&filter%5Btime%5D=&filter%5Btype_id%5D=&page=2

  过滤参数在中间传递,只有最后一个&page=2是key。换句话说,被抓取页面的 URL 如下所示:

  1

2

3

4

  https://www.jiandanxinli.com/experts?&page=1

https://www.jiandanxinli.com/experts?&page=2

...

https://www.jiandanxinli.com/experts?&page=49

  开始在 JdxlSpider(scrapy.Spider) 类中定义起始 URL:如下:

  1

2

3

4

5

6

7

8

  allowed_domains = ["jiandanxinli.com"]

start_urls = ['http://jiandanxinli.com/experts']

start_url_list = []

for i in range(1,50):

start_url_list.extend(['http://jiandanxinli.com/experts?&page=' + str(i)])

start_urls = start_url_list

  问题二:如何抓取节点信息

  在 def parse(self, response): 函数中定义要捕获的内容,并使用 XPath 语法告诉爬虫要捕获的节点位置。

  什么是“怕死”?

  XPath(XML 路径语言)是一种用于从 XML 文档中选择节点的查询语言。此外,XPath 可用于从 XML 文档的内容计算值(例如,字符串、数字或布尔值)。—— 维基

  怎么写XPath?

  感谢 Chrome,它直接提供了 XPath 选择功能。右键需要抓包的位置,点击Inspect,打开chrome-devtools面板:

  

  瞄准要抓取的节点,再次右击,点击复制XPath,XPath路径就被复制了。

  

  不要太高兴。无数次在调试坑中摔倒的00颤抖着告诉你:直接复制的XPath往往不能直接用...

  比如上面那个顾问的名字,chrome提供的路径是:

  1

  //*[@id="content_wrapper"]/div[2]/div[2]/a[5]/div[1]/strong/text()

  但更准确的路径是:

  1

  /div[@class="summary"]/strong/text()

  .

  对于初学者来说,如果之前没有太多写html和css的经验,每一个xpath都需要摸索很久。但这是唯一的出路。经过大量的折腾,您将学会诚实地阅读XPath 文档。

  问题3:如果内容中没有节点怎么办?

  当我抓到顾问的咨询方式、地点、价格等信息时,骗子就来了。

  这个簇的结构是:

  

  文字不收录在标签中!正面和背面都有一个 i 标签!怎么抓啊!

  然后开始了漫长的谷歌之路。终于找到这篇文章:如何使用scrapy提取标签中没有的文本?

  我通过follow::text()获取了一些信息:

  1

2

3

  zx_type = response.xpath('./div[@class="info"]/i/following::text()').extract()[1]

location = response.xpath('./div[@class="info"]/i/following::text()').extract()[2]

price = response.xpath('./div[@class="info"]/i/following::text()').extract()[3]

  这样,每一列都不能有缺失的信息,否则爬取会错位... 暂且处理>。

  问题4:如何抓取多个专家信息

  抓取专家信息后,如何抓取每页10~11位专家信息?查看页面的html,每个专家都在标签下。因此,使用循环来获取具有此功能的所有标签。

  为了缩小范围,在 response.xpath('//a[@class="expert"]') 中传递了父节点的路径。

  1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

  for each in response.xpath('//a[@class="expert"]'):

print(each)

item = JdxlItem()

# 抓取姓名

item['name'] = each.xpath('./div[@class="summary"]/strong/text()').extract()

# 抓取 url

item['url'] = each.xpath('./@href').extract()

# 抓取简介

item['info'] = each.xpath('./div[@class="summary"]//div[@class="content"]/text()').extract()

# 抓取咨询方式、地点、价格等

item['zx_type'] = each.xpath('./div[@class="info"]/i/following::text()').extract()[1]

item['location'] = each.xpath('./div[@class="info"]/i/following::text()').extract()[2]

item['price'] = each.xpath('./div[@class="info"]/i/following::text()').extract()[3]

yield item

  其他配置

  在settings.py文件中添加一个模拟user_agent的模块(需要先用pip安装faker包),设置爬取间隔、头信息等:

  1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

  from faker import Factory

f = Factory.create()

USER_AGENT = f.user_agent()

# Obey robots.txt rules

ROBOTSTXT_OBEY = True

DOWNLOAD_DELAY = 1

DEFAULT_REQUEST_HEADERS = {

'Host': 'www.jiandanxinli.com',

'Accept': '*/*',

'Accept-Encoding': 'gzip, deflate, br',

'Accept-Language': 'zh-CN,zh;q=0.8',

'Cache-Control': 'no-cache',

'Connection': 'Keep-Alive',

}

  测试和抓取

  开始爬行的命令是:

  1

  scrapy crawl counselor

  Crawl 后面跟着 JdxlSpider(scrapy.Spider): 类中定义的爬虫名称。

  尝试先获取 2 个页面:

  1

2

  for i in range(1,3):

start_url_list.extend(['http://jiandanxinli.com/experts?&page=' + str(i)])

  调试过程中的主要问题是没有准确提供节点的xpath,没有抓取到内容。此外,您可能会忘记在 items.py 中设置项目。一般来说,根据错误报告,慢慢寻找,总能找到问题所在。耐心一点。

  输出 csv

  查了官方文档——Scrapy 1.4.0文档和Item Exporters——Scrapy 1.4.0文档中的Feed导出部分,尝试写pipelines,有点复杂并没有成功。

  然后我搜索了Scrapy爬虫框架教程(二)——爬取豆瓣电影TOP250,只是在执行爬虫时设置输出参数:

  1

  scrapy crawl counselor -o output_file.csv

  查看和清理数据

  新建一个 Jupyter Notebook,导入 pandas 包,使用 pd.read_csv 命令查看文件:

  

  获取的链接不完整,完整,输出:

  1

2

  df['url'] = 'http://jiandanxinli.com'+df['url']

df.to_csv('counselor.csv', index=False)

  下一篇文章将继续介绍使用 Pandas 和 Bokeh 的简单数据统计和可视化。

  项目源码请查看00的github repo:

  

  参考

0 个评论

要回复文章请先登录注册


官方客服QQ群

微信人工客服

QQ人工客服


线